Design Configuration

Basic Info
Pricing & Text
URLs & Links
Analytics & Contact
Display Settings
Behavior Settings
Sub-Footer Settings

CSS Editor

Preview Mode
` : ''; // Generate sub-footer content if enabled const subFooterContent = config.subFooter ? ` ` : ''; // Determine account text based on context (matches index.js logic) const accountText = config.account_text_wifi && !config.useOtpFlowFlag ? config.account_text_wifi : config.account_text; // Escape any potential quotes in config values const safeConfig = { title: (config.title || '').replace(/"/g, '"'), subtitle: (config.subtitle || '').replace(/"/g, '"'), service: (config.service || '').replace(/"/g, '"'), description: (config.description || '').replace(/"/g, '"'), service_text: (config.service_text || '').replace(/"/g, '"'), price_text: (config.price_text || '').replace(/"/g, '"'), price_text_otp: (config.price_text_otp || '').replace(/"/g, '"'), logo_url: config.logo_url || '', header_image_url: config.header_image_url || '', terms_url: config.terms_url || '#', cancellation_dial: (config.cancellation_dial || '').replace(/"/g, '"'), help_number: (config.help_number || '').replace(/"/g, '"') }; return ` ${safeConfig.title} ${googleAnalytics}
${resultContent}

Processing your request...

Content Services are currently blocked for this number. If you select ACCEPT you will be allowed to purchase this specific content, but other content services will remain blocked.

${config.useLowercaseCloseButton ? 'x' : 'X'} ${config.displayLogo ? ` ` : ''}
${safeConfig.subtitle} ${safeConfig.service} ${safeConfig.service_text} ${safeConfig.description} ${safeConfig.price_text}
Pay with Vodacom Add to Bill Terms & Conditions
${safeConfig.subtitle} ${safeConfig.service} ${safeConfig.service_text} ${safeConfig.description} ${safeConfig.price_text}
Pay with Vodacom Add to Bill Terms & Conditions
Please include area code: (e.g. 27123456789)

Please enter your 4-digit OTP

To confirm this charge on your Vodacom account/ airtime, please enter the One-Time PIN (OTP) sent to your phone number below to continue:
Resend OTP
Click accept to agree to be charged ${safeConfig.price_text_otp} on your Vodacom Account for ${safeConfig.title}. Terms & Conditions apply.
${subFooterContent} `; } function getFooterDisplay(state, config) { if (state.resultMessage) return 'none'; if (state.msisdnDiv && config.displayFooterOtp) return 'block'; if (state.otpDiv && config.displayFooterMsisdn) return 'block'; return 'none'; } // ============================================================================ // EVENT HANDLERS AND INITIALIZATION // ============================================================================ // Auto-update preview when form fields change function initializeFormWatchers() { const form = document.getElementById('configForm'); form.addEventListener('input', function(event) { clearTimeout(window.updateTimeout); // If the CSS URL field changed, load the CSS and update preview if (event.target.id === 'stylesheet_css_url') { window.updateTimeout = setTimeout(() => { loadCssFromUrl(); // This will automatically call updatePreview() after loading CSS }, 800); // Longer delay for CSS URL changes } else { // For other fields, just update the preview window.updateTimeout = setTimeout(updatePreview, 500); } }); form.addEventListener('change', function(event) { // Handle checkbox changes immediately if (event.target.type === 'checkbox') { clearTimeout(window.updateTimeout); window.updateTimeout = setTimeout(updatePreview, 100); } }); } // File upload handler for JSON configs function initializeFileHandlers() { document.getElementById('jsonFile').addEventListener('change', function(event) { const file = event.target.files[0]; if (file && file.type === 'application/json') { const reader = new FileReader(); reader.onload = function(e) { document.getElementById('jsonInput').value = e.target.result; }; reader.readAsText(file); } else if (file) { showJsonError('Please select a valid JSON file.'); } }); } // Initialize CSS tab functionality function initializeCssTabs() { try { // Set default active tab const rawTab = document.querySelector('.css-tab[onclick*="raw"]'); const propertiesTab = document.querySelector('.css-tab[onclick*="properties"]'); if (rawTab) rawTab.classList.add('active'); if (propertiesTab) propertiesTab.classList.remove('active'); const cssEditor = document.getElementById('cssEditor'); const cssProperties = document.getElementById('cssProperties'); if (cssEditor) cssEditor.style.display = 'block'; if (cssProperties) cssProperties.style.display = 'none'; } catch (error) { console.error('Error initializing CSS tabs:', error); } } // Load default configuration and CSS function loadDefaultConfiguration() { // Set some default values if not already set const defaults = { title: 'XR Academy', subtitle: 'Unlock a World of Learning with MyXRAcademy', price_text: 'R10/ Day with the first day free', price_text_otp: 'R10/ Day with the first day free', account_text: 'on your Vodacom account', account_text_wifi: 'Charged to your mobile account when you switch to mobile data', logo_url: 'https://media-content-storage.b-cdn.net/xra/img/logo_xracademy.png', header_image_url: 'https://media-content-storage.b-cdn.net/xra/img/XR_blp.jpg', stylesheet_css_url: 'https://media-content-storage.b-cdn.net/xra/static/d1.landing.css', content_base_url: 'https://mcb.mediapera.com/api/v2/xcis-callback/za/mobixone', terms_url: 'http://mx.quickpay.mobi/vc/tcs/xr/tc.html', google_tag: 'G-G5LHLRBXE5', cancellation_dial: 'Dial *135*997# to cancel.', help_number: 'Help 0765639425', defaultLandingUrl: 'https://za.myxra.link/', subFooterTncText: 'by clicking subscribe you are accepting the Terms and Conditions', subFooterCopyright: '© 2025 - MYXONE', displayLogo: true, useOtpFlowFlag: true }; // Only set defaults for empty fields Object.keys(defaults).forEach(key => { const field = document.getElementById(key); if (field) { if (field.type === 'checkbox') { if (!field.hasAttribute('data-initialized')) { field.checked = defaults[key] === true; field.setAttribute('data-initialized', 'true'); } } else if (!field.value) { field.value = defaults[key]; } } }); } // Initialize preview with loading message function initializePreview() { const iframe = document.getElementById('previewFrame'); iframe.srcdoc = `

Loading preview...

`; } // Error handling for CSS loading function handleCssLoadError(error) { const cssEditor = document.getElementById('cssEditor'); cssEditor.value = `/* Error loading CSS: ${error.message} */\n\n/* Please check the CSS URL or try again */`; customCss = cssEditor.value; updatePreview(); } // Debug helper function function debugConfiguration() { const formData = new FormData(document.getElementById('configForm')); const config = {}; for (let [key, value] of formData.entries()) { config[key] = value; } console.log('Current Configuration:', config); console.log('Current Preview Mode:', currentPreviewMode); console.log('Custom CSS Length:', customCss.length); console.log('Parsed CSS Selectors:', Object.keys(parsedCss).length); return config; } // Main initialization function function initializeDesignTool() { console.log('🎨 Initializing Design Config Preview Tool...'); try { // Initialize all components loadDefaultConfiguration(); initializeFormWatchers(); initializeFileHandlers(); initializeCssTabs(); initializePreview(); // Load CSS and generate initial preview with error handling setTimeout(() => { const cssUrl = document.getElementById('stylesheet_css_url').value; if (cssUrl) { loadCssFromUrl() .then(() => { updatePreview(); console.log('✅ Design tool initialized successfully'); }) .catch(error => { console.warn('CSS loading failed, proceeding with fallback:', error); // Use fallback CSS customCss = ` body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background: #f0f0f0; } .error-message { color: #e74c3c; font-size: 1.2em; text-align: center; margin: 20px 0; } .error-details { color: #666; font-size: 0.9em; text-align: center; margin: 10px 0; } .home-button { background: #3498db; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } `; document.getElementById('cssEditor').value = customCss; updatePreview(); console.log('✅ Design tool initialized with fallback CSS'); }); } else { updatePreview(); console.log('✅ Design tool initialized without CSS'); } }, 100); // Make debug function available globally window.debugConfig = debugConfiguration; } catch (error) { console.error('❌ Failed to initialize design tool:', error); // Still try to show something try { updatePreview(); } catch (updateError) { console.error('❌ Failed to update preview during error recovery:', updateError); // Show basic error message in iframe const iframe = document.getElementById('previewFrame'); if (iframe) { iframe.srcdoc = `

Preview Error

Unable to generate preview. Please check the configuration and try again.

Error: ${error.message}

`; } } } } // ============================================================================ // DOCUMENT READY AND STARTUP // ============================================================================ // Initialize when DOM is ready document.addEventListener('DOMContentLoaded', function() { initializeDesignTool(); }); // Fallback initialization window.addEventListener('load', function() { // Double-check initialization in case DOMContentLoaded didn't fire if (!document.getElementById('previewFrame').srcdoc.includes('Loading preview')) { return; // Already initialized } setTimeout(initializeDesignTool, 100); }); // Handle page visibility changes (reload preview when tab becomes visible) document.addEventListener('visibilitychange', function() { if (!document.hidden) { // Page became visible, refresh preview in case something changed setTimeout(updatePreview, 200); } }); // Global error handler window.addEventListener('error', function(event) { console.error('Global error in design tool:', event.error); // Try to recover by showing a basic preview if (event.error && event.error.message && event.error.message.includes('CSS')) { handleCssLoadError(event.error); } }); console.log('🚀 Design Config Preview Tool loaded and ready');