/** * AutoApp Builder - Frontend JavaScript */ // ─── Character Counter ────────────────────────────────────────────── const promptInput = document.getElementById('promptInput'); const charCount = document.getElementById('charCount'); if (promptInput && charCount) { promptInput.addEventListener('input', () => { const len = promptInput.value.length; charCount.textContent = `${len} / 2000`; if (len > 1800) { charCount.classList.add('text-yellow-500'); } else { charCount.classList.remove('text-yellow-500'); } }); } // ─── Example Buttons ──────────────────────────────────────────────── document.querySelectorAll('.example-btn').forEach(btn => { btn.addEventListener('click', () => { const prompt = btn.getAttribute('data-prompt'); if (promptInput && prompt) { promptInput.value = prompt; promptInput.dispatchEvent(new Event('input')); promptInput.focus(); // Scroll to textarea promptInput.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }); }); // ─── SDK Preference Toggle ────────────────────────────────────────── document.querySelectorAll('.sdk-option').forEach(label => { label.addEventListener('click', () => { // Remove active styles from all document.querySelectorAll('.sdk-option').forEach(l => { l.classList.remove('bg-cyan-500/20', 'text-cyan-400'); l.classList.add('text-dark-400'); }); // Add active style to clicked label.classList.add('bg-cyan-500/20', 'text-cyan-400'); label.classList.remove('text-dark-400'); }); }); // ─── Advanced Options Toggle ──────────────────────────────────────── const toggleAdvanced = document.getElementById('toggleAdvanced'); const advancedPanel = document.getElementById('advancedPanel'); const advancedArrow = document.getElementById('advancedArrow'); if (toggleAdvanced && advancedPanel) { toggleAdvanced.addEventListener('click', () => { advancedPanel.classList.toggle('hidden'); if (advancedArrow) { advancedArrow.style.transform = advancedPanel.classList.contains('hidden') ? 'rotate(0deg)' : 'rotate(90deg)'; } }); } // ─── Form Submission Loading State ────────────────────────────────── const generateForm = document.getElementById('generateForm'); if (generateForm) { generateForm.addEventListener('submit', () => { const btn = document.getElementById('submitBtn'); const text = document.getElementById('submitText'); const spinner = document.getElementById('submitSpinner'); if (btn) btn.disabled = true; if (text) text.textContent = 'Generating...'; if (spinner) spinner.classList.remove('hidden'); btn.classList.add('opacity-75', 'cursor-not-allowed'); }); } const editForm = document.getElementById('editForm'); if (editForm) { editForm.addEventListener('submit', () => { const btn = document.getElementById('editBtn'); const text = document.getElementById('editText'); const spinner = document.getElementById('editSpinner'); if (btn) btn.disabled = true; if (text) text.textContent = 'Editing...'; if (spinner) spinner.classList.remove('hidden'); btn.classList.add('opacity-75', 'cursor-not-allowed'); }); } // ─── File Selection & Code Preview (Result Page) ──────────────────── function selectFile(filepath) { if (typeof fileData === 'undefined') return; const content = fileData[filepath]; if (content === undefined) return; // Update active state in tree document.querySelectorAll('.file-tree-item').forEach(item => { item.classList.remove('active'); }); const activeItem = document.querySelector(`[data-filepath="${filepath}"]`); if (activeItem) activeItem.classList.add('active'); // Update filename display const fileNameEl = document.getElementById('currentFileName'); if (fileNameEl) fileNameEl.textContent = filepath; // Determine language for syntax highlighting const lang = getLanguage(filepath); // Show code block, hide placeholder const placeholder = document.getElementById('codePlaceholder'); const codeBlock = document.getElementById('codeBlock'); const codeContent = document.getElementById('codeContent'); if (placeholder) placeholder.classList.add('hidden'); if (codeBlock) codeBlock.classList.remove('hidden'); if (codeContent) { // Escape HTML entities codeContent.textContent = content; codeContent.className = `language-${lang}`; // Re-highlight if (window.Prism) { Prism.highlightElement(codeContent); } } } function getLanguage(filepath) { const ext = filepath.split('.').pop().toLowerCase(); const langMap = { 'py': 'python', 'js': 'javascript', 'ts': 'javascript', 'html': 'markup', 'htm': 'markup', 'css': 'css', 'md': 'markdown', 'yaml': 'yaml', 'yml': 'yaml', 'json': 'javascript', 'sh': 'bash', 'bash': 'bash', 'dockerfile': 'docker', 'txt': 'text', 'toml': 'text', 'cfg': 'text', 'ini': 'text', 'gitignore': 'text', }; // Handle Dockerfile specifically if (filepath.toLowerCase() === 'dockerfile') return 'docker'; return langMap[ext] || 'text'; } // ─── Copy Code ────────────────────────────────────────────────────── function copyCode() { const codeContent = document.getElementById('codeContent'); if (!codeContent) return; const text = codeContent.textContent; navigator.clipboard.writeText(text).then(() => { const btn = document.getElementById('copyBtn'); if (btn) { const originalHTML = btn.innerHTML; btn.innerHTML = ' Copied!'; btn.classList.add('text-emerald-400'); setTimeout(() => { btn.innerHTML = originalHTML; btn.classList.remove('text-emerald-400'); }, 2000); } }).catch(() => { // Fallback: select text const range = document.createRange(); range.selectNodeContents(codeContent); const sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); }); } // ─── Architecture Diagram Toggle ──────────────────────────────────── function toggleDiagram() { const panel = document.getElementById('diagramPanel'); const toggle = document.getElementById('diagramToggle'); if (panel) { panel.classList.toggle('hidden'); if (toggle) { toggle.textContent = panel.classList.contains('hidden') ? 'Show' : 'Hide'; } } } // ─── Keyboard Shortcuts ───────────────────────────────────────────── document.addEventListener('keydown', (e) => { // Ctrl/Cmd + Enter to submit form if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { const form = document.getElementById('generateForm') || document.getElementById('editForm'); if (form) { form.dispatchEvent(new Event('submit', { bubbles: true })); form.submit(); } } });