Universal Component Code Scaffolder

Accelerate your development of reusable UI components. This tool allows developers and design system architects to rapidly generate boilerplate code for common UI patterns.

Free use limit reached. Unlock unlimited access.

You've used all your free attempts. Subscribe to Pixel Office Hub or unlock this app to continue generating component code without limits.

Recommended

Showcase Hub Bundle

Unlock unlimited access to this and 19+ other powerful AI tools.

One-Time Access

Unlock this single application forever with a one-time payment.

Crypto Micro-payment

Pay securely with cryptocurrencies like Solana or Bitcoin.

Sign In to Pixel Office Hub

Access your Pixel Office account to manage subscriptions.

Complete Your Crypto Payment

Scan the QR code or send the exact amount to the address below.

Crypto Payment QR Code

Amount: USD

Currency:

Address:

Do NOT refresh this page. Payment will be verified automatically.

`; break; case 'web-components': code = ` // ${name}.js class ${name} extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.initialRender(); } static get observedAttributes() { return [${parsedProps.map(p => `'${p.name}'`).join(', ')}]; } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { this[name] = newValue; this.render(); // Re-render when attributes change } } initialRender() { this.shadowRoot.innerHTML = \`

${name}

This is a ${type} Web Component.

${parsedSlots.length > 0 ? `\n \n ${parsedSlots.map(s => ``).join('\n ')}` : ''}
\`; this.addEventListeners(); } render() { // Update dynamic parts of the component without re-rendering everything if possible // For simplicity, we re-run initialRender for attribute changes this.initialRender(); } addEventListeners() { // const button = this.shadowRoot.getElementById('my-button'); // if (button) { // button.addEventListener('click', () => { // console.log('Button clicked in Web Component!'); // // if (this.onClick && typeof this.onClick === 'function') this.onClick(); // }); // } } } customElements.define('${name.toLowerCase()}', ${name}); `; break; default: code = `// Unsupported framework: ${framework}`; } return code; } function parseProps(propsString) { let props = []; if (!propsString) return props; try { // Try parsing as JSON first const jsonProps = JSON.parse(propsString); for (const key in jsonProps) { if (Object.hasOwnProperty.call(jsonProps, key)) { props.push({ name: key, type: jsonProps[key] }); } } } catch (e) { // If JSON parsing fails, assume comma-separated propsString.split(',').forEach(p => { const trimmedP = p.trim(); if (trimmedP) { // Attempt to infer type if not specified let name = trimmedP; let type = 'string'; // Default to string if (trimmedP.includes(':')) { const parts = trimmedP.split(':'); name = parts[0].trim(); type = parts[1].trim(); } props.push({ name: name, type: type }); } }); } return props; } function parseSlots(slotsString) { if (!slotsString) return []; return slotsString.split(',').map(s => s.trim()).filter(Boolean); } async function generateCode() { if (!isUnlocked()) { const currentTrialCount = incrementTrialCount(); if (currentTrialCount > 3) { showPaymentOverlay(); return; } } showSpinner(); generateCodeBtn.disabled = true; statusMessageDiv.classList.add('hidden'); generatedCodeBlock.textContent = translations[currentLanguage]['generatingCode']; resultArea.classList.remove('hidden'); downloadCodeBtn.classList.add('hidden'); const name = componentNameInput.value.trim(); const type = componentTypeSelect.value; const props = componentPropsTextarea.value.trim(); const slots = componentSlotsInput.value.trim(); const logic = componentLogicTextarea.value.trim(); const framework = targetFrameworkSelect.value; if (!name) { showStatusMessage(translations[currentLanguage]['codeGenerationError'] + " " + translations[currentLanguage]['labelComponentName'] + " " + (currentLanguage === 'en' ? 'cannot be empty.' : 'nesmí být prázdné.'), 'error'); generatedCodeBlock.textContent = ''; generateCodeBtn.disabled = false; hideSpinner(); return; } // Simulate API call delay await new Promise(resolve => setTimeout(resolve, 1000)); try { const generated = generateBoilerplate(name, type, props, slots, logic, framework); generatedCodeBlock.textContent = generated; showStatusMessage(translations[currentLanguage]['codeGeneratedSuccess'], 'success'); downloadCodeBtn.classList.remove('hidden'); // Show download button after successful generation } catch (error) { console.error("Code generation error:", error); showStatusMessage(translations[currentLanguage]['codeGenerationError'], 'error'); generatedCodeBlock.textContent = ''; } finally { generateCodeBtn.disabled = false; hideSpinner(); } } function generateWhatsAppMessage() { const name = componentNameInput.value.trim(); const type = componentTypeSelect.options[componentTypeSelect.selectedIndex].text; const props = componentPropsTextarea.value.trim() || "N/A"; const slots = componentSlotsInput.value.trim() || "N/A"; const logic = componentLogicTextarea.value.trim() || "N/A"; const framework = targetFrameworkSelect.options[targetFrameworkSelect.selectedIndex].text; const message = `*${translations[currentLanguage]['widgetTitle']} - Code Request Summary*\n` + `-----------------------------------------------------\n` + `*${translations[currentLanguage]['labelComponentName']}*: ${name}\n` + `*${translations[currentLanguage]['labelComponentType']}*: ${type}\n` + `*${translations[currentLanguage]['labelComponentProps']}*: \n\`\`\`\n${props}\n\`\`\`\n` + `*${translations[currentLanguage]['labelComponentSlots']}*: ${slots}\n` + `*${translations[currentLanguage]['labelComponentLogic']}*: \n\`\`\`\n${logic}\n\`\`\`\n` + `*${translations[currentLanguage]['labelTargetFramework']}*: ${framework}\n\n` + `${translations[currentLanguage]['downloadingCode']}\n` + `_Pixel Office Bot_`; return message; } function downloadCodeViaWhatsApp() { const message = generateWhatsAppMessage(); const whatsappUrl = `https://wa.me/${WHATSAPP_NUMBER}?text=${encodeURIComponent(message)}`; window.open(whatsappUrl, '_blank'); showStatusMessage(translations[currentLanguage]['downloadingCode'], 'success'); } // --- Firebase Auth Functions --- function showAuthModal() { hideOverlay(paymentOverlay); authErrorMessageDiv.textContent = ''; isSignUpMode = false; // Reset to sign-in mode document.getElementById('auth-modal-title').setAttribute('data-i18n', 'signInTitle'); document.getElementById('auth-modal-description').setAttribute('data-i18n', 'signInDescription'); emailAuthBtn.setAttribute('data-i18n', 'signInButton'); toggleAuthModeBtn.setAttribute('data-i18n', 'switchToSignUp'); updateContent(); // Re-localize dynamically updated elements showOverlay(authOverlay); } function toggleAuthMode() { isSignUpMode = !isSignUpMode; authErrorMessageDiv.textContent = ''; // Clear errors on toggle if (isSignUpMode) { document.getElementById('auth-modal-title').setAttribute('data-i18n', 'signUpTitle'); document.getElementById('auth-modal-description').setAttribute('data-i18n', 'signUpDescription'); emailAuthBtn.setAttribute('data-i18n', 'signUpButton'); toggleAuthModeBtn.setAttribute('data-i18n', 'switchToSignIn'); } else { document.getElementById('auth-modal-title').setAttribute('data-i18n', 'signInTitle'); document.getElementById('auth-modal-description').setAttribute('data-i18n', 'signInDescription'); emailAuthBtn.setAttribute('data-i18n', 'signInButton'); toggleAuthModeBtn.setAttribute('data-i18n', 'switchToSignUp'); } updateContent(); } async function handleEmailAuth() { const email = authEmailInput.value; const password = authPasswordInput.value; authErrorMessageDiv.textContent = ''; if (!email || !password) { authErrorMessageDiv.textContent = translations[currentLanguage]['authError'] + (currentLanguage === 'en' ? 'Email and password cannot be empty.' : 'E-mail a heslo nesmí být prázdné.'); return; } showSpinner(); try { if (isSignUpMode) { await auth.createUserWithEmailAndPassword(email, password); } else { await auth.signInWithEmailAndPassword(email, password); } // Auth state listener will handle unlocking/subscription check hideOverlay(authOverlay); } catch (error) { authErrorMessageDiv.textContent = translations[currentLanguage]['authError'] + error.message; console.error("Auth error:", error); } finally { hideSpinner(); } } async function handleGoogleAuth() { showSpinner(); const provider = new firebase.auth.GoogleAuthProvider(); try { await auth.signInWithPopup(provider); // Auth state listener will handle unlocking/subscription check hideOverlay(authOverlay); } catch (error) { authErrorMessageDiv.textContent = translations[currentLanguage]['authError'] + error.message; console.error("Google Auth error:", error); } finally { hideSpinner(); } } // --- Payment API Calls --- async function checkSubscription(email) { if (!email) return false; showStatusMessage(translations[currentLanguage]['loadingSubscription'], 'info'); try { const response = await fetch(`${API_BASE_URL}/check-subscription?email=${encodeURIComponent(email)}`); const data = await response.json(); if (data.active) { unlockWidget(); showStatusMessage(translations[currentLanguage]['subscriptionActive'], 'success'); return true; } else { showStatusMessage(translations[currentLanguage]['subscriptionInactive'], 'info'); return false; } } catch (error) { console.error("Error checking subscription:", error); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); return false; } } async function createHubSubscription(email, userId) { showSpinner(); try { const response = await fetch(`${API_BASE_URL}/create-hub-subscription`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, userId }) }); const data = await response.json(); if (data.url) { window.location.href = data.url; // Redirect to Stripe Checkout } else { showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'] + " " + (currentLanguage === 'en' ? 'No checkout URL.' : 'Žádná URL pro platbu.'), 'error'); } } catch (error) { console.error("Error creating Hub subscription:", error); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); } finally { hideSpinner(); } } async function createSingleAppPaymentSession() { showSpinner(); try { const response = await fetch(`${API_BASE_URL}/create-session`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug: WIDGET_SLUG, amount: 199, // $1.99 in cents widgetName: translations[currentLanguage]['widgetTitle'] }) }); const data = await response.json(); if (data.url) { window.location.href = data.url; // Redirect to Stripe Checkout } else { showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'] + " " + (currentLanguage === 'en' ? 'No checkout URL.' : 'Žádná URL pro platbu.'), 'error'); } } catch (error) { console.error("Error creating single app session:", error); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); } finally { hideSpinner(); } } async function requestCryptoPayment() { showSpinner(); try { const response = await fetch(`${API_BASE_URL}/request-crypto`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug: WIDGET_SLUG, amount: 199, // $1.99 in cents widgetName: translations[currentLanguage]['widgetTitle'] }) }); const data = await response.json(); if (data.success && data.address && data.amount && data.currency && data.paymentId) { cryptoQrCodeImg.src = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${data.address}`; cryptoAmountSpan.textContent = (data.amount / 100).toFixed(2); cryptoCurrencySpan.textContent = data.currency; cryptoAddressDiv.textContent = data.address; hideOverlay(paymentOverlay); showOverlay(cryptoOverlay); startCryptoPolling(data.paymentId); } else { showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'] + " " + (currentLanguage === 'en' ? 'Invalid crypto payment data.' : 'Neplatná data pro krypto platbu.'), 'error'); } } catch (error) { console.error("Error requesting crypto payment:", error); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); } finally { hideSpinner(); } } function startCryptoPolling(paymentId) { // Clear any existing polling interval if (cryptoPollingInterval) { clearInterval(cryptoPollingInterval); } cryptoPollingInterval = setInterval(async () => { try { const response = await fetch(`${API_BASE_URL}/verify-crypto?paymentId=${paymentId}`); const data = await response.json(); if (data.verified) { clearInterval(cryptoPollingInterval); unlockWidget(); showStatusMessage(translations[currentLanguage]['paymentVerificationSuccess'], 'success'); hideOverlay(cryptoOverlay); } else if (data.status === 'expired' || data.status === 'failed') { clearInterval(cryptoPollingInterval); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'] + " " + (currentLanguage === 'en' ? 'Crypto payment ' + data.status : 'Krypto platba ' + data.status), 'error'); hideOverlay(cryptoOverlay); } } catch (error) { console.error("Error polling crypto payment:", error); clearInterval(cryptoPollingInterval); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); hideOverlay(cryptoOverlay); } }, 10000); // Poll every 10 seconds } function stopCryptoPolling() { if (cryptoPollingInterval) { clearInterval(cryptoPollingInterval); cryptoPollingInterval = null; } } // --- Stripe Session Verification on Load --- async function verifyStripeSession(sessionId) { showSpinner(); showStatusMessage(translations[currentLanguage]['paymentProcessing'], 'info'); try { const response = await fetch(`${API_BASE_URL}/verify-session?session_id=${sessionId}`); const data = await response.json(); if (data.verified) { unlockWidget(); showStatusMessage(translations[currentLanguage]['paymentVerificationSuccess'], 'success'); } else { showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); } } catch (error) { console.error("Error verifying Stripe session:", error); showStatusMessage(translations[currentLanguage]['paymentVerificationFailed'], 'error'); } finally { hideSpinner(); // Clear URL parameters const url = new URL(window.location.href); url.searchParams.delete('status'); url.searchParams.delete('session_id'); url.searchParams.delete('subscription_status'); window.history.replaceState({}, document.title, url.toString()); } } // --- Event Listeners --- generateCodeBtn.addEventListener('click', generateCode); downloadCodeBtn.addEventListener('click', downloadCodeViaWhatsApp); unlockSingleAppBtn.addEventListener('click', createSingleAppPaymentSession); payCryptoBtn.addEventListener('click', requestCryptoPayment); emailAuthBtn.addEventListener('click', handleEmailAuth); googleAuthBtn.addEventListener('click', handleGoogleAuth); toggleAuthModeBtn.addEventListener('click', toggleAuthMode); cryptoCloseButton.addEventListener('click', () => { hideOverlay(cryptoOverlay); stopCryptoPolling(); }); copyAddressButton.addEventListener('click', () => { const address = cryptoAddressDiv.textContent; navigator.clipboard.writeText(address).then(() => { showStatusMessage(translations[currentLanguage]['copiedToClipboard'], 'success'); }).catch(err => { console.error('Failed to copy text: ', err); showStatusMessage(translations[currentLanguage]['codeGenerationError'] + (currentLanguage === 'en' ? 'Failed to copy.' : 'Kopírování selhalo.'), 'error'); }); }); // Close auth modal if clicked outside authOverlay.addEventListener('click', (event) => { if (event.target === authOverlay) { hideOverlay(authOverlay); } }); // --- Initialization on Page Load --- auth.onAuthStateChanged(async user => { currentUser = user; if (user) { console.log("Firebase user logged in:", user.email); showStatusMessage(translations[currentLanguage]['authLoggedIn'] + user.email, 'info'); await checkSubscription(user.email); updateHubAuthSection(user); // Update hub card if user logs in after overlay shown } else { console.log("No Firebase user logged in."); showStatusMessage(translations[currentLanguage]['authNotLoggedIn'], 'info'); updateHubAuthSection(null); } checkAndShowPaymentOverlay(); // Always check for payment overlay after auth state is known }); document.addEventListener('DOMContentLoaded', () => { const urlParams = new URLSearchParams(window.location.search); const status = urlParams.get('status'); const subscriptionStatus = urlParams.get('subscription_status'); const sessionId = urlParams.get('session_id'); if (status === 'success' && sessionId) { verifyStripeSession(sessionId); } else if (subscriptionStatus === 'success' && sessionId) { // For Hub subscriptions, wait for auth.onAuthStateChanged to complete, // which will then call checkSubscription and verify the hub status. // We just need to clear the URL parameters here. const url = new URL(window.location.href); url.searchParams.delete('status'); url.searchParams.delete('session_id'); url.searchParams.delete('subscription_status'); window.history.replaceState({}, document.title, url.toString()); showStatusMessage(translations[currentLanguage]['paymentVerificationSuccess'], 'success'); } else { // If no payment redirect, check the auth state to determine trial/unlocked status // The auth.onAuthStateChanged listener handles the initial check and overlay display. } updateContent(); // Initial localization pass // Ensure footer link is localized if footerText contains a variable part document.querySelector('footer a').href = PIXEL_OFFICE_HUB_URL; document.querySelector('footer a').target = "_blank"; });