Właściwości

Dostosuj szczegóły

Edytuj tytuł, opis, przyciski, obrazy i kolory. Zmiany zapisują się natychmiast — bez ryzyka utraty pracy.

Wybierz sekcję z listy po lewej, aby edytować jej właściwości. Kliknij ikonę sekcji — pojawią się tu pola do wypełnienia, dopasowane do typu treści.

Dobre praktyki: pisz krótkie, konkretne nagłówki. Unikaj żargonu branżowego. Każdy nagłówek powinien obiecywać konkretną korzyść, którą klient natychmiast zrozumie — dzięki temu strona skuteczniej konwertuje odwiedzających w kupujących.

`; } if (int.fb_pixel) { scripts += ` `; } if (int.gtm_id) { scripts += ` `; } return scripts; } }; // === INLINE EDITING === const InlineEditor = { active: false, currentElement: null, currentPath: null, init() { const iframe = document.getElementById('previewFrame'); if (!iframe?.contentDocument) return; iframe.contentDocument.addEventListener('dblclick', (e) => { if (!this.active) return; e.preventDefault(); const el = e.target; if (this.isEditable(el)) { this.openEditor(el); } }); }, toggle() { this.active = !this.active; const btn = document.getElementById('inlineEditBtn'); if (btn) { btn.classList.toggle('active', this.active); btn.textContent = this.active ? '✏️ Tryb edycji ON' : '✏️ Edytuj tekst'; } const iframe = document.getElementById('previewFrame'); if (iframe?.contentDocument) { iframe.contentDocument.body.style.cursor = this.active ? 'text' : 'default'; } showToast(this.active ? 'Kliknij 2x na tekst aby edytować' : 'Tryb edycji wyłączony', 'success'); }, isEditable(el) { const editableTags = ['H1','H2','H3','H4','H5','H6','P','SPAN','A','LI','BUTTON','LABEL']; return editableTags.includes(el.tagName) && el.textContent.trim().length > 0; }, openEditor(el) { this.currentElement = el; const text = el.textContent.trim(); const tagName = el.tagName.toLowerCase(); const overlay = document.createElement('div'); overlay.className = 'inline-edit-overlay'; overlay.onclick = (e) => { if (e.target === overlay) this.closeEditor(); }; const isLong = text.length > 100; overlay.innerHTML = `

✏️ Edycja: <${tagName}>

${isLong ? `` : `` }
`; document.body.appendChild(overlay); document.getElementById('inlineEditText')?.focus(); }, closeEditor() { document.querySelector('.inline-edit-overlay')?.remove(); this.currentElement = null; }, save() { const newText = document.getElementById('inlineEditText')?.value; if (!newText || !this.currentElement) { this.closeEditor(); return; } this.currentElement.textContent = newText; this.updateState(); this.closeEditor(); showToast('Tekst zaktualizowany', 'success'); }, updateState() { const iframe = document.getElementById('previewFrame'); if (!iframe?.contentDocument) return; const html = iframe.contentDocument.documentElement.outerHTML; fetch('/optimizer/api/landing/v2/save-html.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: EditorState.sessionId, html: html }) }); saveToHistory(); } }; function toggleInlineEdit() { InlineEditor.toggle(); } // === FONT PICKER === const FontPicker = { fonts: [ // Sans-serif { name: 'Inter', category: 'sans-serif', polish: true }, { name: 'Roboto', category: 'sans-serif', polish: true }, { name: 'Open Sans', category: 'sans-serif', polish: true }, { name: 'Lato', category: 'sans-serif', polish: true }, { name: 'Montserrat', category: 'sans-serif', polish: true }, { name: 'Poppins', category: 'sans-serif', polish: true }, { name: 'Raleway', category: 'sans-serif', polish: true }, { name: 'Nunito', category: 'sans-serif', polish: true }, { name: 'Work Sans', category: 'sans-serif', polish: true }, { name: 'Rubik', category: 'sans-serif', polish: true }, { name: 'Mulish', category: 'sans-serif', polish: true }, { name: 'Quicksand', category: 'sans-serif', polish: true }, { name: 'Barlow', category: 'sans-serif', polish: true }, { name: 'Manrope', category: 'sans-serif', polish: true }, { name: 'DM Sans', category: 'sans-serif', polish: true }, { name: 'Outfit', category: 'sans-serif', polish: true }, { name: 'Plus Jakarta Sans', category: 'sans-serif', polish: true }, { name: 'Space Grotesk', category: 'sans-serif', polish: true }, { name: 'Lexend', category: 'sans-serif', polish: true }, { name: 'Figtree', category: 'sans-serif', polish: true }, // Serif { name: 'Playfair Display', category: 'serif', polish: true }, { name: 'Merriweather', category: 'serif', polish: true }, { name: 'Lora', category: 'serif', polish: true }, { name: 'Source Serif Pro', category: 'serif', polish: true }, { name: 'PT Serif', category: 'serif', polish: true }, { name: 'Crimson Pro', category: 'serif', polish: true }, { name: 'Libre Baskerville', category: 'serif', polish: true }, { name: 'Cormorant Garamond', category: 'serif', polish: true }, { name: 'EB Garamond', category: 'serif', polish: true }, { name: 'Spectral', category: 'serif', polish: true }, // Monospace { name: 'Fira Code', category: 'monospace', polish: true }, { name: 'JetBrains Mono', category: 'monospace', polish: true }, { name: 'Source Code Pro', category: 'monospace', polish: true }, { name: 'IBM Plex Mono', category: 'monospace', polish: true }, { name: 'Roboto Mono', category: 'monospace', polish: true } ], loadedFonts: new Set(['Inter']), loadFont(fontName) { if (this.loadedFonts.has(fontName)) return; const link = document.createElement('link'); link.href = `https://fonts.googleapis.com/css2?family=${fontName.replace(/ /g, '+')}:wght@400;500;600;700&subset=latin,latin-ext&display=swap`; link.rel = 'stylesheet'; document.head.appendChild(link); this.loadedFonts.add(fontName); }, loadFontInIframe(fontName) { const iframe = document.getElementById('previewFrame'); if (!iframe || !iframe.contentDocument) return; const doc = iframe.contentDocument; if (doc.querySelector(`link[href*="${fontName.replace(/ /g, '+')}"]`)) return; const link = doc.createElement('link'); link.href = `https://fonts.googleapis.com/css2?family=${fontName.replace(/ /g, '+')}:wght@400;500;600;700&subset=latin,latin-ext&display=swap`; link.rel = 'stylesheet'; doc.head.appendChild(link); } }; function renderFontPicker() { const currentHeading = EditorState.state?.typography?.heading || 'Inter'; const currentBody = EditorState.state?.typography?.body || 'Inter'; const fontOptions = FontPicker.fonts.map(f => `` ).join(''); return `

🔤 Typografia

Przykładowy Nagłówek
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
`; } function changeFont(type, fontName) { FontPicker.loadFont(fontName); FontPicker.loadFontInIframe(fontName); if (!EditorState.state.typography) { EditorState.state.typography = { heading: 'Inter', body: 'Inter' }; } EditorState.state.typography[type] = fontName; // Update preview in picker const select = document.getElementById(type === 'heading' ? 'fontHeading' : 'fontBody'); if (select) select.style.fontFamily = `'${fontName}', sans-serif`; const preview = document.getElementById(type === 'heading' ? 'fontPreviewHeading' : 'fontPreviewBody'); if (preview) preview.style.fontFamily = `'${fontName}', sans-serif`; // Apply to iframe applyFontToPreview(type, fontName); saveToHistory(); showToast(`Czcionka ${type === 'heading' ? 'nagłówków' : 'tekstu'} zmieniona`, 'success'); } function applyFontToPreview(type, fontName) { const iframe = document.getElementById('previewFrame'); if (!iframe || !iframe.contentDocument) return; const doc = iframe.contentDocument; if (type === 'heading') { doc.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(el => { el.style.fontFamily = `'${fontName}', sans-serif`; }); } else { doc.body.style.fontFamily = `'${fontName}', sans-serif`; doc.querySelectorAll('p, span, a, li, td, th, label, button').forEach(el => { if (!el.closest('h1, h2, h3, h4, h5, h6')) { el.style.fontFamily = `'${fontName}', sans-serif`; } }); } } function applyAllFontsToPreview() { if (!EditorState.state?.typography) return; const { heading, body } = EditorState.state.typography; if (heading) { FontPicker.loadFontInIframe(heading); applyFontToPreview('heading', heading); } if (body) { FontPicker.loadFontInIframe(body); applyFontToPreview('body', body); } }