1-50 thèmes
Mes Thèmes (.ZIP)
Catalogue Officiel
Modèles Gratuits (12)
\n` }, { name: 'config/settings_schema.json', content: JSON.stringify([ { "name": "theme_info", "theme_name": themeName, "theme_author": "Wantedmarkets", "theme_version": "2.1.0", "theme_documentation_url": "https://wantedmarkets.com", "theme_support_url": "https://wantedmarkets.com/support" } ], null, 2) } ]; const blob = createZipBlob(files); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = `theme_${cleanSlug}_shopify2.zip`; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 100); } function createZipBlob(files) { function getCrcTable() { let c, table = []; for (let n = 0; n < 256; n++) { c = n; for (let k = 0; k < 8; k++) c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); table[n] = c; } return table; } const crcTable = getCrcTable(); function calcCrc32(bytes) { let crc = 0 ^ (-1); for (let i = 0; i < bytes.length; i++) { crc = (crc >>> 8) ^ crcTable[(crc ^ bytes[i]) & 0xFF]; } return (crc ^ (-1)) >>> 0; } const encoder = new TextEncoder(); let fileEntries = []; let localOffset = 0; let parts = []; for (let f of files) { const nameBytes = encoder.encode(f.name); const dataBytes = encoder.encode(f.content); const crc = calcCrc32(dataBytes); const size = dataBytes.length; const localHeader = new Uint8Array(30); const dv = new DataView(localHeader.buffer); dv.setUint32(0, 0x04034b50, true); dv.setUint16(4, 20, true); dv.setUint16(6, 0, true); dv.setUint16(8, 0, true); dv.setUint16(10, 0, true); dv.setUint16(12, 0, true); dv.setUint32(14, crc, true); dv.setUint32(18, size, true); dv.setUint32(22, size, true); dv.setUint16(26, nameBytes.length, true); dv.setUint16(28, 0, true); parts.push(localHeader, nameBytes, dataBytes); fileEntries.push({ nameBytes, crc, size, offset: localOffset }); localOffset += localHeader.length + nameBytes.length + dataBytes.length; } const cdStart = localOffset; let cdSize = 0; for (let fe of fileEntries) { const cdHeader = new Uint8Array(46); const dv = new DataView(cdHeader.buffer); dv.setUint32(0, 0x02014b50, true); dv.setUint16(4, 20, true); dv.setUint16(6, 20, true); dv.setUint16(8, 0, true); dv.setUint16(10, 0, true); dv.setUint16(12, 0, true); dv.setUint16(14, 0, true); dv.setUint32(16, fe.crc, true); dv.setUint32(20, fe.size, true); dv.setUint32(24, fe.size, true); dv.setUint16(28, fe.nameBytes.length, true); dv.setUint16(30, 0, true); dv.setUint16(32, 0, true); dv.setUint16(34, 0, true); dv.setUint16(36, 0, true); dv.setUint32(38, 0, true); dv.setUint32(42, fe.offset, true); parts.push(cdHeader, fe.nameBytes); cdSize += cdHeader.length + fe.nameBytes.length; } const eocd = new Uint8Array(22); const dv = new DataView(eocd.buffer); dv.setUint32(0, 0x06054b50, true); dv.setUint16(4, 0, true); dv.setUint16(6, 0, true); dv.setUint16(8, fileEntries.length, true); dv.setUint16(10, fileEntries.length, true); dv.setUint32(12, cdSize, true); dv.setUint32(16, cdStart, true); dv.setUint16(20, 0, true); parts.push(eocd); return new Blob(parts, { type: 'application/zip' }); } async function startSubscriptionCheckout(plan) { const planNames = { 'pro': 'Plan Pro (49 $/mois - 1 crédit thème/mois)', 'agency': 'Plan Agence (99 $/mois - 3 crédits thèmes/mois + licence commerciale)', 'pack3': 'Pack 3 Thèmes (199 $ - 3 crédits permanents)', 'pack10': 'Pack 10 Thèmes (499 $ - 10 crédits + licence commerciale)' }; const planTitle = planNames[plan] || 'Abonnement Wantedmarkets'; try { const res = await fetch('/api/create-subscription-checkout', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ plan }) }); const data = await res.json(); if (data.checkout_url) { window.location.href = data.checkout_url; } else { showToast(`Stripe Checkout préparé : ${planTitle}`); } } catch (err) { showToast(`Souscription initiée : ${planTitle}`); } } function toggleSettingsMenu(event) { if (event) event.stopPropagation(); const popup = document.getElementById('settingsPopup'); if (popup) popup.classList.toggle('hidden'); } document.addEventListener('click', (e) => { const popup = document.getElementById('settingsPopup'); if (popup && !popup.classList.contains('hidden') && !e.target.closest('#settingsPopup')) { popup.classList.add('hidden'); } const userPopup = document.getElementById('userAccountPopup'); if (userPopup && !userPopup.classList.contains('hidden') && !e.target.closest('#userAccountPopup') && !e.target.closest('#authHeaderContainer')) { userPopup.classList.add('hidden'); } const acDropdown = document.getElementById('autocompleteDropdown'); if (acDropdown && !acDropdown.classList.contains('hidden') && !e.target.closest('#autocompleteDropdown') && !e.target.closest('#urlForm')) { acDropdown.classList.add('hidden'); } }); function showToast(msg) { const toast = document.createElement('div'); toast.className = "fixed bottom-5 left-1/2 -translate-x-1/2 bg-[#303134] text-white border border-[#5f6368] px-4 py-2.5 rounded-full text-xs font-semibold shadow-2xl z-50 transition-all duration-300"; toast.innerText = msg; document.body.appendChild(toast); setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 300); }, 3000); } // --- TYPEWRITER ANIMATED PLACEHOLDER --- const placeholderPhrases = [ "https://themes.shopify.com/themes/taiga", "https://gymshark.com", "https://themes.shopify.com/themes/publisher", "Streetwear oversize minimaliste", "Luxe & Bijoux haute conversion", "Colle ici le lien du site ou thème Shopify à cloner..." ]; let phraseIndex = 0; let charIndex = 0; let isDeleting = false; let isUserFocused = false; const urlInput = document.getElementById('urlInput'); if (urlInput) { urlInput.addEventListener('focus', () => { isUserFocused = true; }); } if (urlInput) { urlInput.addEventListener('blur', () => { if (!urlInput.value) isUserFocused = false; }); } function typeWriterEffect() { if (!urlInput) return; if (isUserFocused || urlInput.value) { setTimeout(typeWriterEffect, 500); return; } const currentPhrase = placeholderPhrases[phraseIndex]; if (isDeleting) { if (urlInput) urlInput.setAttribute('placeholder', currentPhrase.substring(0, charIndex - 1)); charIndex--; } else { if (urlInput) urlInput.setAttribute('placeholder', currentPhrase.substring(0, charIndex + 1)); charIndex++; } let speed = isDeleting ? 30 : 65; if (!isDeleting && charIndex === currentPhrase.length) { speed = 2200; isDeleting = true; } else if (isDeleting && charIndex === 0) { isDeleting = false; phraseIndex = (phraseIndex + 1) % placeholderPhrases.length; speed = 400; } setTimeout(typeWriterEffect, speed); } // --- POPUP ACCOUNT & PREFERENCE HELPERS --- let currentAppLanguage = 'français'; function toggleAppLanguage() { currentAppLanguage = (currentAppLanguage === 'français') ? 'English' : 'français'; const langEl = document.getElementById('accountLanguageBadge'); if (langEl) langEl.innerText = currentAppLanguage; showToast(`Langue définie sur ${currentAppLanguage}`); } function clearRecentSearchHistory() { localStorage.removeItem('wm_search_history'); showToast('Historique des 30 dernières minutes supprimé'); closeUserAccountPopup(); } // --- URL HASH ROUTER (PERSISTENCE SUR ACTUALISATION & SOUS-HASHES) --- async function handleRoute() { const hash = window.location.hash.replace(/^#/, ''); if (hash === 'ads' || hash === 'publicite' || hash.startsWith('ads-')) { window.location.href = '/ads'; } else if (hash === 'comment-ca-marche' || hash === 'how-it-works' || hash.startsWith('how-')) { window.location.href = '/comment-ca-marche'; } else if (hash.startsWith('theme=') || hash.startsWith('search')) { window.location.href = '/catalogue#' + hash; } else if (hash === 'checkout' || hash === 'commande' || hash === 'panier') { openCheckoutModal({ type: 'cart' }); } else if (hash === 'boutique' || hash === 'catalog') { window.location.href = '/catalogue'; } else if (hash === 'pricing' || hash === 'tarifs' || hash.startsWith('pricing-')) { window.location.href = '/tarifs'; } else if (hash === 'starred' || hash === 'favoris' || hash === 'collections') { await openDashboardView('starred', false); } else { await openDashboardView('purchased', false); } } window.addEventListener('hashchange', () => { handleRoute(); }); // INIT ALL initTheme(); renderUserAuthState(); initAdsStorage(); typeWriterEffect(); loadCatalog().then(() => { handleRoute(); }); // Register PWA Service Worker if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js') .then((reg) => console.log('Wantedmarkets PWA actif:', reg.scope)) .catch((err) => console.log('Service Worker notice:', err)); }); }
✓ Achat récent validé · il y a 3 min
Thème Beauvoir (Shopify 2.0)
Export .ZIP délivré à Alexandre M. (Paris)