upskill-event-manager/fix-all-css-issues.js
bengizmo 993a820a84 feat: Add comprehensive development artifacts to repository
- Add 26 documentation files including test reports, deployment guides, and troubleshooting documentation
- Include 3 CSV data files for trainer imports and user registration tracking
- Add 43 JavaScript test files covering mobile optimization, Safari compatibility, and E2E testing
- Include 18 PHP utility files for debugging, geocoding, and data analysis
- Add 12 shell scripts for deployment verification, user management, and database operations
- Update .gitignore with whitelist patterns for development files, documentation, and CSV data

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 12:26:11 -03:00

263 lines
No EOL
8.8 KiB
JavaScript
Executable file

#!/usr/bin/env node
/**
* Comprehensive CSS Fix - Restore all CSS files to valid syntax
*/
const fs = require('fs');
const path = require('path');
const CSS_DIR = './assets/css';
// CSS files that need fixing
const cssFiles = [
'hvac-common.css',
'hvac-dashboard.css',
'hvac-registration.css',
'hvac-event-summary.css',
'hvac-email-attendees.css',
'hvac-event-registration.css',
'hvac-certificate-reports.css',
'hvac-email-templates.css',
'hvac-master-dashboard.css',
'hvac-communication-templates.css'
];
function fixCSSContent(content, fileName) {
console.log(`\n🔧 Processing ${fileName}...`);
// Step 1: Remove duplicate semicolons and fix malformed lines
content = content.replace(/;\s*;+/g, ';');
content = content.replace(/;\s*\n\s*;/g, ';\n');
// Step 2: Fix duplicate vendor prefixes
content = content.replace(/-webkit--webkit-/g, '-webkit-');
content = content.replace(/-moz--moz-/g, '-moz-');
content = content.replace(/-ms--ms-/g, '-ms-');
content = content.replace(/-o--o-/g, '-o-');
// Step 3: Fix multiple consecutive vendor prefixes
content = content.replace(/(-webkit-){2,}/g, '-webkit-');
content = content.replace(/(-moz-){2,}/g, '-moz-');
content = content.replace(/(-ms-){2,}/g, '-ms-');
content = content.replace(/(-o-){2,}/g, '-o-');
// Step 4: Fix border-radius with excessive prefixes
content = content.replace(/-webkit-webkit-webkit-webkit-webkit-webkit-border-radius:/g, '-webkit-border-radius:');
content = content.replace(/-webkit-webkit-border-radius:/g, '-webkit-border-radius:');
content = content.replace(/border-radius:\s*([^;]+);\s*border-radius:\s*([^;]+);/g, 'border-radius: $1;');
// Step 5: Fix box-shadow with excessive prefixes
content = content.replace(/-webkit-webkit-webkit-box-shadow:/g, '-webkit-box-shadow:');
content = content.replace(/-webkit-webkit-box-shadow:/g, '-webkit-box-shadow:');
// Step 6: Fix malformed transform properties
content = content.replace(/text--webkit-transform:/g, 'text-transform:');
content = content.replace(/text--moz-transform:/g, 'text-transform:');
content = content.replace(/text--ms-transform:/g, 'text-transform:');
// Step 7: Fix CSS custom property issues
content = content.replace(/--hvac--webkit-border-radius:/g, '--hvac-border-radius:');
// Step 8: Clean up duplicate fallback comments
content = content.replace(/\/\* IE fallback \*\/;\s*\/\* IE fallback \*\/;/g, ' /* IE fallback */');
content = content.replace(/\/\* IE fallback \*\/;\s*\n\s*([^:]+): ([^;]+); \/\* IE fallback \*\/;/g, '$1: $2; /* IE fallback */');
// Step 9: Fix broken rule structures
let rules = [];
let currentRule = '';
let braceCount = 0;
let inComment = false;
let inString = false;
let stringChar = '';
for (let i = 0; i < content.length; i++) {
const char = content[i];
const prevChar = i > 0 ? content[i - 1] : '';
const nextChar = i < content.length - 1 ? content[i + 1] : '';
// Handle comments
if (!inString && char === '/' && nextChar === '*') {
inComment = true;
currentRule += char;
continue;
}
if (!inString && inComment && char === '*' && nextChar === '/') {
inComment = false;
currentRule += char;
continue;
}
// Handle strings
if (!inComment && (char === '"' || char === "'") && prevChar !== '\\') {
if (!inString) {
inString = true;
stringChar = char;
} else if (char === stringChar) {
inString = false;
stringChar = '';
}
}
currentRule += char;
// Count braces
if (!inComment && !inString) {
if (char === '{') {
braceCount++;
} else if (char === '}') {
braceCount--;
// Complete rule found
if (braceCount === 0 && currentRule.trim()) {
rules.push(currentRule.trim());
currentRule = '';
}
}
}
}
// Add any remaining content
if (currentRule.trim()) {
// If we have unclosed braces, try to close them
while (braceCount > 0) {
currentRule += '\n}';
braceCount--;
}
rules.push(currentRule.trim());
}
// Step 10: Reconstruct the CSS with proper formatting
let fixedCSS = '';
const headerComments = [];
const rootRules = [];
const mediaQueries = [];
const keyframes = [];
const normalRules = [];
for (const rule of rules) {
if (rule.startsWith('/*') && !rule.includes('{')) {
headerComments.push(rule);
} else if (rule.startsWith(':root')) {
rootRules.push(rule);
} else if (rule.startsWith('@media')) {
mediaQueries.push(rule);
} else if (rule.startsWith('@keyframes')) {
keyframes.push(rule);
} else {
normalRules.push(rule);
}
}
// Rebuild in proper order
if (headerComments.length > 0) {
fixedCSS += headerComments.join('\n') + '\n\n';
}
if (rootRules.length > 0) {
fixedCSS += rootRules.join('\n\n') + '\n\n';
}
if (normalRules.length > 0) {
fixedCSS += normalRules.join('\n\n') + '\n\n';
}
if (keyframes.length > 0) {
fixedCSS += keyframes.join('\n\n') + '\n\n';
}
if (mediaQueries.length > 0) {
fixedCSS += mediaQueries.join('\n\n') + '\n';
}
// Final cleanup
fixedCSS = fixedCSS.replace(/\n{3,}/g, '\n\n');
fixedCSS = fixedCSS.trim() + '\n';
return fixedCSS;
}
function validateCSS(content) {
const openBraces = (content.match(/{/g) || []).length;
const closeBraces = (content.match(/}/g) || []).length;
const hasRoot = content.includes(':root');
const hasRules = content.match(/\.[a-zA-Z][\w-]*\s*{/) || content.match(/#[a-zA-Z][\w-]*\s*{/) || content.match(/[a-zA-Z]+\s*{/);
return {
balanced: openBraces === closeBraces,
openBraces,
closeBraces,
hasRoot,
hasRules: !!hasRules,
valid: openBraces === closeBraces && openBraces > 0
};
}
function main() {
console.log('HVAC Community Events - Comprehensive CSS Fix');
console.log('='.repeat(60));
if (!fs.existsSync(CSS_DIR)) {
console.error(`CSS directory not found: ${CSS_DIR}`);
process.exit(1);
}
let totalFixed = 0;
let totalErrors = 0;
for (const file of cssFiles) {
const filePath = path.join(CSS_DIR, file);
if (!fs.existsSync(filePath)) {
console.log(`⚠️ File not found: ${file}`);
continue;
}
try {
// Read the corrupted content
let content = fs.readFileSync(filePath, 'utf8');
// Validate before
const beforeValidation = validateCSS(content);
console.log(` Before: ${beforeValidation.openBraces} open, ${beforeValidation.closeBraces} close braces`);
// Fix the content
content = fixCSSContent(content, file);
// Validate after
const afterValidation = validateCSS(content);
console.log(` After: ${afterValidation.openBraces} open, ${afterValidation.closeBraces} close braces`);
if (afterValidation.valid) {
// Write the fixed content
fs.writeFileSync(filePath, content, 'utf8');
console.log(` ✅ Fixed and saved`);
totalFixed++;
} else {
console.log(` ❌ Still has issues - needs manual review`);
totalErrors++;
// Save to a .fixed file for manual review
fs.writeFileSync(filePath + '.fixed', content, 'utf8');
console.log(` 💾 Saved partially fixed version to ${file}.fixed`);
}
} catch (error) {
console.error(` ❌ Error processing ${file}:`, error.message);
totalErrors++;
}
}
console.log('\n' + '='.repeat(60));
console.log(`✅ Successfully fixed: ${totalFixed} files`);
if (totalErrors > 0) {
console.log(`⚠️ Errors encountered: ${totalErrors} files`);
console.log('\nFiles with .fixed extension need manual review.');
}
console.log('\nNext steps:');
console.log('1. Review the fixed CSS files');
console.log('2. Test in browser for visual issues');
console.log('3. Run CSS validation tools');
}
if (require.main === module) {
main();
}
module.exports = { fixCSSContent, validateCSS };