Rituais Exclusivos
Desperte seus desejos mais sombrios no Caldeirão Digital
Desperte seus desejos mais sombrios no Caldeirão Digital
AVISO IMPORTANTE: Todo conteúdo será enviado apenas após confirmação do pagamento. Conteúdo exclusivo e sem reembolso.
Select a pack above
After confirming, you will be redirected to complete payment by credit/debit card.
✅ Secure and encrypted payment
Select a package above
AVISO IMPORTANTE: Todas as chamadas serão realizadas apenas após confirmação do pagamento. O pagamento deve ser enviado antes do agendamento.
After confirming, you will be redirected to complete payment by credit/debit card.
✅ Secure and encrypted payment
Select a video above
AVISO IMPORTANTE: Todo conteúdo será enviado apenas após confirmação do pagamento . Vídeos exclusivos e sem reembolso.
Select an item above
⏱️ Prazo de Entrega: 15 a 28 dias úteis
📮 Envio discreto via Correios • 🎁 Embalagem neutra e
sigilosa
📍 Entrega em todo o Brasil • 📱 Código de rastreamento será
enviado
AVISO IMPORTANTE: Todas as peças são enviadas discretamente após confirmação do pagamento . Produtos únicos e sem reembolso.
Pagamento via PIX: akemisato030@gmail.com
📦 Envio discreto e sigiloso em embalagem neutra
⏱️ Prazo de entrega: 15 a 28 dias úteis
Select a VIP plan above
AVISO IMPORTANTE: A assinatura VIP é renovada automaticamente. Todos os benefícios são ativados imediatamente após confirmação do pagamento.
🔄 Renovação automática conforme plano escolhido
👑 Ativação imediata após confirmação do pagamento
${selectedPricing.time}
${selectedPricing.price}
`; confirmBtn.disabled = false; confirmBtn.classList.add("confirm-call"); confirmBtn.textContent = "Confirmar Pedido"; confirmBtn.style.opacity = "1"; confirmBtn.style.cursor = "pointer"; } else { selectedPackage.innerHTML = ` `; confirmBtn.disabled = true; confirmBtn.classList.remove("confirm-call"); confirmBtn.textContent = translations[currentLanguage]?.["button-select-package-first"] || "Select a Package First"; confirmBtn.style.opacity = "0.5"; confirmBtn.style.cursor = "not-allowed"; } } // Função para selecionar método de pagamento window.selectPaymentMethod = function (method, context) { console.log( `Selecionado método de pagamento: ${method} para contexto: ${context}` ); // Atualizar campo hidden const hiddenField = document.getElementById( `paymentMethod${context.charAt(0).toUpperCase() + context.slice(1)}` ); if (hiddenField) { hiddenField.value = method; } // Mostrar/ocultar informações de pagamento const pixInfo = document.getElementById( `pixInfo${context.charAt(0).toUpperCase() + context.slice(1)}` ); const creditInfo = document.getElementById( `creditInfo${context.charAt(0).toUpperCase() + context.slice(1)}` ); if (method === "pix") { if (pixInfo) pixInfo.style.display = "block"; if (creditInfo) creditInfo.style.display = "none"; } else if (method === "credit") { if (pixInfo) pixInfo.style.display = "none"; if (creditInfo) creditInfo.style.display = "block"; // 💲 Ensure the Stripe URL is kept in sync when switching to credit if (context === "call" && selectedPricing && selectedPricing.time) { const normalized = (selectedPricing.time || "").trim(); let stripeUrl = STRIPE_URLS[normalized] || STRIPE_URLS[normalized.toLowerCase()]; if (!stripeUrl) { const alt = normalized .replace(/\b1 hour\b/gi, "1 hora") .replace(/\b1 heure\b/gi, "1 hora") .replace(/\bhour\b/gi, "hora") .replace(/\bheure\b/gi, "hora"); stripeUrl = STRIPE_URLS[alt] || STRIPE_URLS[alt.toLowerCase()]; } if (stripeUrl) { selectedPricing.stripeUrl = stripeUrl; console.log(`🔗 Stripe URL sincronizado: ${stripeUrl}`); } else { console.warn("⚠️ Nenhuma URL Stripe encontrada para o pacote selecionado."); } } if (context === "photos" && selectedPhotoPack && selectedPhotoPack.name) { const key = (selectedPhotoPack.name || "").trim(); let url = STRIPE_PHOTO_URLS[key] || STRIPE_PHOTO_URLS[key.toLowerCase?.()]; if (url) { selectedPhotoPack.stripeUrl = url; console.log(`🔗 Stripe URL fotos sincronizado: ${url}`); } } if (context === "videos" && selectedVideo) { try { // First try explicit mapping by video name const key = (selectedVideo.name || "").trim(); let url = STRIPE_VIDEO_URLS[key] || STRIPE_VIDEO_URLS[key?.toLowerCase?.()]; // Fallback: map by duration to generic STRIPE_URLS (same as calls) if (!url) { const dur = (selectedVideo.duration || "").toLowerCase(); const candidates = [ "5 min","10 min","15 min","20 min","25 min","30 min", "35 min","40 min","45 min","50 min","55 min","1 hora","1h" ]; let matched = candidates.find(c => dur.includes(c.replace('1 hora','1h')) || dur.includes(c)); if (matched === '1h') matched = '1 hora'; if (matched && STRIPE_URLS[matched]) { url = STRIPE_URLS[matched]; } } if (url) { selectedVideo.stripeUrl = url; console.log(`🔗 Stripe URL vídeos sincronizado: ${url}`); } else { console.warn('⚠️ Nenhuma URL Stripe encontrada para o vídeo selecionado. Configure STRIPE_VIDEO_URLS.'); } } catch(_) {} } } // Atualizar visual dos botões const allOptions = document.querySelectorAll(".payment-option"); allOptions.forEach((opt) => { opt.style.opacity = "0.6"; opt.style.transform = "scale(1)"; }); event.target.closest(".payment-option").style.opacity = "1"; event.target.closest(".payment-option").style.transform = "scale(1.05)"; if (paymentPendingData) { updatePaymentMethod(method === "credit" ? "card" : method); } // Revalidar campos validateAllFields(); }; // Processar pagamento de chamada window.processCallPayment = function () { const paymentMethod = document.getElementById("paymentMethodCall")?.value; if (!paymentMethod) { alert(translations[currentLanguage]?.["alert-select-payment-method"] || "Please select a payment method."); return; } if (paymentMethod === "pix") { sendToWhatsApp(); } else if (paymentMethod === "credit") { if (selectedPricing && selectedPricing.stripeUrl) { console.log( `🔗 Redirecionando para Stripe: ${selectedPricing.stripeUrl}` ); window.location.href = selectedPricing.stripeUrl; // Redirect to the Stripe URL } else { alert( translations[currentLanguage]?.["alert-no-stripe-url"] || "⚠️ No Stripe URL found for the selected package." ); } } }; // Processar pagamento de fotos window.processPhotoPayment = function () { const paymentMethod = document.getElementById( "paymentMethodPhotos" )?.value; if (!paymentMethod) { alert(translations[currentLanguage]?.["alert-select-payment-method"] || "Please select a payment method."); return; } if (paymentMethod === "pix") { sendPhotosToWhatsApp(); } else if (paymentMethod === "credit") { processCreditCard("photos"); } }; window.processCreditCard = function (context) { // Aqui você pode integrar com um gateway de pagamento como: // - Stripe // - PayPal // - Mercado Pago // - PagSeguro // - Etc. if (context === "photos") { if (selectedPhotoPack && selectedPhotoPack.stripeUrl) { window.location.href = selectedPhotoPack.stripeUrl; return; } } if (context === "videos") { if (selectedVideo) { // If explicit URL present, use it if (selectedVideo.stripeUrl) { window.location.href = selectedVideo.stripeUrl; return; } // Fallback: map duration to generic STRIPE_URLS try { const dur = (selectedVideo.duration || '').toLowerCase(); const candidates = [ '5 min','10 min','15 min','20 min','25 min','30 min', '35 min','40 min','45 min','50 min','55 min','1 hora','1h' ]; let matched = candidates.find(c => dur.includes(c.replace('1 hora','1h')) || dur.includes(c)); if (matched === '1h') matched = '1 hora'; if (matched && STRIPE_URLS[matched]) { window.location.href = STRIPE_URLS[matched]; return; } } catch(_) {} } } alert("⚠️ Nenhuma URL Stripe configurada. Use os placeholders em STRIPE_PHOTO_URLS/STRIPE_VIDEO_URLS."); }; async function sendToWhatsApp() { if (!selectedPricing) { alert(translations[currentLanguage]?.["alert-select-package"] || "Please select a package first."); return; } // Obter informações do cliente const customerName = document .getElementById("customerName") .value.trim(); const customerPhone = document .getElementById("customerPhone") .value.trim(); if (!customerName || !customerPhone) { alert(translations[currentLanguage]?.["alert-fill-required-fields"] || "Please fill in all required fields (*)."); return; } // Save user info to file await saveUserInfo(customerName, customerPhone, "video_call", { duration: selectedPricing.time, price: selectedPricing.price, }); const messages = { pt: `🔮 *AGENDAMENTO DE CHAMADA MÍSTICA* 🔮 👋 Olá Akemi! Gostaria de agendar uma chamada de vídeo: 👤 *Nome:* ${customerName} 📱 *Telefone:* ${customerPhone} ⏰ *Duração:* ${selectedPricing.time} 💰 *Valor:* ${selectedPricing.price} 💰 *🟢 CHAVE PIX OFICIAL 🟢* 💳 akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entendo que a chamada só será realizada após a confirmação do pagamento. Aguardo confirmação para enviar o comprovante! ✨`, en: `🔮 *MYSTICAL CALL BOOKING* 🔮 👋 Hello Akemi! I would like to schedule a video call: 👤 *Name:* ${customerName} 📱 *Phone:* ${customerPhone} ⏰ *Duration:* ${selectedPricing.time} 💰 *Price:* ${selectedPricing.price} 💳 *PIX Key:* akemisato030@gmail.com ⚠️ *IMPORTANT:* I understand that the call will only be made after payment confirmation. I await confirmation to send the receipt! ✨`, es: `🔮 *RESERVA DE LLAMADA MÍSTICA* 🔮 👋 ¡Hola Akemi! Me gustaría programar una videollamada: 👤 *Nombre:* ${customerName} 📱 *Teléfono:* ${customerPhone} ⏰ *Duración:* ${selectedPricing.time} 💰 *Precio:* ${selectedPricing.price} 💳 *Clave PIX:* akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entiendo que la llamada solo se realizará después de la confirmación del pago. ¡Espero confirmación para enviar el comprobante! ✨`, fr: `🔮 *RÉSERVATION D'APPEL MYSTIQUE* 🔮 👋 Bonjour Akemi! Je voudrais programmer un appel vidéo: 👤 *Nom:* ${customerName} 📱 *Téléphone:* ${customerPhone} ⏰ *Durée:* ${selectedPricing.time} 💰 *Prix:* ${selectedPricing.price} 💳 *Clé PIX:* akemisato030@gmail.com ⚠️ *IMPORTANT:* Je comprends que l'appel ne sera effectué qu'après confirmation du paiement. J'attends la confirmation pour envoyer le reçu! ✨`, }; const message = messages[currentLanguage]; const whatsappUrl = `https://wa.me/447848188486?text=${encodeURIComponent( message )}`; window.open(whatsappUrl, "_blank"); closeModal(); } function closeModal() { const modal = document.getElementById("videoCallModal"); if (modal) { modal.classList.remove("show"); setTimeout(() => { modal.style.setProperty("display", "none", "important"); modal.style.setProperty("visibility", "hidden", "important"); modal.style.setProperty("opacity", "0", "important"); modal.style.setProperty("z-index", "-9999", "important"); modal.style.setProperty("left", "-9999px", "important"); modal.style.setProperty("top", "-9999px", "important"); modal.style.setProperty("pointer-events", "none", "important"); }, 300); } try { triggerBannerFromModal(selectedPricing?.price || null, "call"); } catch (error) { console.warn("Erro ao acionar banner de pagamento para chamadas:", error); } } // Photos and Packs functions function updatePhotoPricing() { const photosPricingGrid = document.getElementById("photosPricingGrid"); if (photosPricingGrid) { photosPricingGrid.innerHTML = ""; const photoPrices = photosPricingData[currentLanguage]; photoPrices.forEach((pack) => { const card = document.createElement("div"); card.className = "pricing-card"; card.innerHTML = `${selectedPhotoPack.name}
${selectedPhotoPack.price}
📸 ${selectedPhotoPack.photos} fotos exclusivas
`; confirmBtn.disabled = false; confirmBtn.textContent = translations[currentLanguage]["confirm-photos-order"] || "Confirmar Pedido"; confirmBtn.classList.add("confirm-photos"); confirmBtn.style.opacity = "1"; confirmBtn.style.cursor = "pointer"; } else { selectedPackage.innerHTML = ` `; confirmBtn.disabled = true; confirmBtn.textContent = translations[currentLanguage]?.["button-select-pack-first"] || "Select a Pack First"; confirmBtn.style.opacity = "0.5"; confirmBtn.style.cursor = "not-allowed"; } } async function sendPhotosToWhatsApp() { if (!selectedPhotoPack) { alert(translations[currentLanguage]?.["alert-select-pack"] || "Please select a pack first."); return; } // Obter informações do cliente const customerName = document .getElementById("customerNamePhotos") .value.trim(); const customerPhone = document .getElementById("customerPhonePhotos") .value.trim(); const customerObservations = document .getElementById("customerObservationsPhotos") .value.trim(); if (!customerName || !customerPhone) { alert(translations[currentLanguage]?.["alert-fill-required-fields"] || "Please fill in all required fields (*)."); return; } // Save user info to file await saveUserInfo(customerName, customerPhone, "photos", { pack_name: selectedPhotoPack.name, price: selectedPhotoPack.price, photo_count: selectedPhotoPack.photos, observations: customerObservations || "None", }); const messages = { pt: `🖤 *PEDIDO DE FOTOS E PACKS MÍSTICOS* 🖤 👋 Olá Akemi! Gostaria de adquirir: 👤 *Nome:* ${customerName} 📱 *Telefone:* ${customerPhone} 📦 *Pack:* ${selectedPhotoPack.name} 💰 *Valor:* ${selectedPhotoPack.price} 📸 *Quantidade:* ${selectedPhotoPack.photos} fotos exclusivas 💳 *Chave PIX:* akemisato030@gmail.com ${customerObservations ? `📝 *Observações:* ${customerObservations}` : ""} ⚠️ *IMPORTANTE:* Entendo que o conteúdo será enviado apenas após confirmação do pagamento. Aguardo confirmação para enviar o comprovante! ✨`, en: `🖤 *MYSTICAL PHOTOS AND PACKS ORDER* 🖤 👋 Hello Akemi! I would like to purchase: 👤 *Name:* ${customerName} 📱 *Phone:* ${customerPhone} 📦 *Pack:* ${selectedPhotoPack.name} 💰 *Price:* ${selectedPhotoPack.price} 📸 *Quantity:* ${selectedPhotoPack.photos} exclusive photos 💳 *PIX Key:* akemisato030@gmail.com ${ customerObservations ? `📝 *Observations:* ${customerObservations}` : "" } ⚠️ *IMPORTANT:* I understand that content will be sent only after payment confirmation. I await confirmation to send the receipt! ✨`, es: `🖤 *PEDIDO DE FOTOS Y PACKS MÍSTICOS* 🖤 👋 ¡Hola Akemi! Me gustaría adquirir: 👤 *Nombre:* ${customerName} 📱 *Teléfono:* ${customerPhone} 📦 *Pack:* ${selectedPhotoPack.name} 💰 *Precio:* ${selectedPhotoPack.price} 📸 *Cantidad:* ${selectedPhotoPack.photos} fotos exclusivas 💳 *Clave PIX:* akemisato030@gmail.com ${ customerObservations ? `📝 *Observaciones:* ${customerObservations}` : "" } ⚠️ *IMPORTANTE:* Entiendo que el contenido será enviado solo después de la confirmación del pago. ¡Espero confirmación para enviar el comprobante! ✨`, fr: `🖤 *COMMANDE DE PHOTOS ET PACKS MYSTIQUES* 🖤 👋 Bonjour Akemi! Je voudrais acquérir: 👤 *Nom:* ${customerName} 📱 *Téléphone:* ${customerPhone} 📦 *Pack:* ${selectedPhotoPack.name} 💰 *Prix:* ${selectedPhotoPack.price} 📸 *Quantité:* ${selectedPhotoPack.photos} photos exclusives 💳 *Clé PIX:* akemisato030@gmail.com ${ customerObservations ? `📝 *Observations:* ${customerObservations}` : "" } ⚠️ *IMPORTANT:* Je comprends que le contenu sera envoyé uniquement après confirmation du paiement. J'attends la confirmation pour envoyer le reçu! ✨`, }; const message = messages[currentLanguage]; const whatsappUrl = `https://wa.me/447848188486?text=${encodeURIComponent( message )}`; window.open(whatsappUrl, "_blank"); closePhotosModal(); } function closePhotosModal() { const modal = document.getElementById("photosModal"); if (modal) { modal.classList.remove("show"); setTimeout(() => { modal.style.cssText = "display: none !important; visibility: hidden !important; opacity: 0 !important; z-index: -9999 !important; position: fixed !important; left: -9999px !important; top: -9999px !important; pointer-events: none !important;"; }, 300); } try { triggerBannerFromModal(selectedPhotoPack?.price || null, "photos"); } catch (error) { console.warn("Erro ao acionar banner de pagamento para fotos:", error); } } // Video upload functions function uploadVideo(containerNumber) { const fileInput = document.getElementById(`video-${containerNumber}`); if (fileInput) { fileInput.click(); } } async function handleVideoUpload(containerNumber, input) { const file = input.files[0]; if (file) { // Verificar se é um arquivo de vídeo if (!file.type.startsWith("video/")) { alert(translations[currentLanguage]?.["alert-select-video-files-only"] || "Please select video files only!"); return; } // Verificar tamanho (40MB) if (file.size > 40 * 1024 * 1024) { alert("Arquivo muito grande! Máximo 40MB."); return; } // Encontrar o container pai const container = input.closest(".video-container"); const uploadArea = container.querySelector(".upload-area"); // Mostrar loading container.innerHTML = `Processando vídeo...
Clique para fazer upload
📹 MP4, AVI, MOV | 📏 Max: 40MB${selectedVideo.name}
${selectedVideo.price}
⏱️ ${selectedVideo.duration}
${selectedVideo.category}
`; confirmBtn.disabled = false; // Set action based on payment method const method = document.getElementById("paymentMethodVideos")?.value; if (method === "credit") { confirmBtn.onclick = () => processVideosPayment(); confirmBtn.textContent = translations[currentLanguage]["confirm-videos-order"] || "Confirmar Pedido"; } else { confirmBtn.onclick = () => sendVideosToWhatsApp(); confirmBtn.textContent = translations[currentLanguage]["confirm-videos-order"] || "Confirmar Pedido"; } confirmBtn.style.opacity = "1"; confirmBtn.style.cursor = "pointer"; } else { selectedPackage.innerHTML = ` `; confirmBtn.disabled = true; confirmBtn.textContent = translations[currentLanguage]?.["button-select-video-first"] || "Select a Video First"; confirmBtn.style.opacity = "0.5"; confirmBtn.style.cursor = "not-allowed"; } } async function sendVideosToWhatsApp() { if (!selectedVideo) { alert(translations[currentLanguage]?.["alert-select-video"] || "Please select a video first."); return; } // Obter informações do cliente const customerName = document .getElementById("customerNameVideos") .value.trim(); const customerPhone = document .getElementById("customerPhoneVideos") .value.trim(); if (!customerName || !customerPhone) { alert(translations[currentLanguage]?.["alert-fill-required-fields"] || "Please fill in all required fields (*)."); return; } // Save user info to file await saveUserInfo(customerName, customerPhone, "videos", { video_name: selectedVideo.name, price: selectedVideo.price, duration: selectedVideo.duration, category: selectedVideo.category, }); const messages = { pt: `⚡ *PEDIDO DE VÍDEOS MÍSTICOS* ⚡ 👋 Olá Akemi! Gostaria de adquirir: 👤 *Nome:* ${customerName} 📱 *Telefone:* ${customerPhone} 🎬 *Vídeo:* ${selectedVideo.name} 💰 *Valor:* ${selectedVideo.price} ⏱️ *Duração:* ${selectedVideo.duration} 📂 *Categoria:* ${selectedVideo.category} 💳 *Chave PIX:* akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entendo que o conteúdo será enviado apenas após confirmação do pagamento. Aguardo confirmação para enviar o comprovante! ✨`, en: `⚡ *MYSTICAL VIDEOS ORDER* ⚡ 👋 Hello Akemi! I would like to purchase: 👤 *Name:* ${customerName} 📱 *Phone:* ${customerPhone} 🎬 *Video:* ${selectedVideo.name} 💰 *Price:* ${selectedVideo.price} ⏱️ *Duration:* ${selectedVideo.duration} 📂 *Category:* ${selectedVideo.category} 💳 *PIX Key:* akemisato030@gmail.com ⚠️ *IMPORTANT:* I understand that content will be sent only after payment confirmation. I await confirmation to send the receipt! ✨`, es: `⚡ *PEDIDO DE VIDEOS MÍSTICOS* ⚡ 👋 ¡Hola Akemi! Me gustaría adquirir: 👤 *Nombre:* ${customerName} 📱 *Teléfono:* ${customerPhone} 🎬 *Video:* ${selectedVideo.name} 💰 *Precio:* ${selectedVideo.price} ⏱️ *Duración:* ${selectedVideo.duration} 📂 *Categoría:* ${selectedVideo.category} 💳 *Clave PIX:* akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entiendo que el contenido será enviado solo después de la confirmación del pago. ¡Espero confirmación para enviar el comprobante! ✨`, fr: `⚡ *COMMANDE DE VIDÉOS MYSTIQUES* ⚡ 👋 Bonjour Akemi! Je voudrais acquérir: 👤 *Nom:* ${customerName} 📱 *Téléphone:* ${customerPhone} 🎬 *Vidéo:* ${selectedVideo.name} 💰 *Prix:* ${selectedVideo.price} ⏱️ *Durée:* ${selectedVideo.duration} 📂 *Catégorie:* ${selectedVideo.category} 💳 *Clé PIX:* akemisato030@gmail.com ⚠️ *IMPORTANT:* Je comprends que le contenu sera envoyé uniquement après confirmation du paiement. J'attends la confirmation pour envoyer le reçu! ✨`, }; const message = messages[currentLanguage]; const whatsappUrl = `https://wa.me/447848188486?text=${encodeURIComponent( message )}`; window.open(whatsappUrl, "_blank"); closeVideosModal(); } // Processar pagamento de vídeos window.processVideosPayment = function () { const method = document.getElementById("paymentMethodVideos")?.value; if (!method) { alert(translations[currentLanguage]?.["alert-select-payment-method"] || "Please select a payment method."); return; } if (method === "pix") { sendVideosToWhatsApp(); } else if (method === "credit") { processCreditCard("videos"); } }; function closeVideosModal() { const modal = document.getElementById("videosModal"); if (modal) { modal.classList.remove("show"); setTimeout(() => { modal.style.cssText = "display: none !important; visibility: hidden !important; opacity: 0 !important; z-index: -9999 !important; position: fixed !important; left: -9999px !important; top: -9999px !important; pointer-events: none !important;"; }, 300); } try { triggerBannerFromModal(selectedVideo?.price || null, "videos"); } catch (error) { console.warn("Erro ao acionar banner de pagamento para vídeos:", error); } } // VIP functions function updateVIPPricing() { console.log("👑 updateVIPPricing() - INICIADO"); const vipPricingGrid = document.getElementById("vipPricingGrid"); console.log( "📋 Grid VIP encontrado?", vipPricingGrid ? "✅ SIM" : "❌ NÃO" ); if (!vipPricingGrid) { console.error("❌ CRÍTICO: Element vipPricingGrid não encontrado!"); return; } try { // Limpar grid existente vipPricingGrid.innerHTML = ""; console.log("🧹 Grid VIP limpo"); // Verificar dados VIP if (!vipPlansData || !vipPlansData[currentLanguage]) { console.error( "❌ Dados VIP não encontrados para idioma:", currentLanguage ); return; } const vipPlans = vipPlansData[currentLanguage]; console.log( `💎 ${vipPlans.length} planos VIP encontrados para idioma ${currentLanguage}` ); // Criar cards para cada plano vipPlans.forEach((plan, index) => { console.log( `📝 Criando card VIP ${index + 1}/${vipPlans.length}: ${ plan.name }` ); const card = document.createElement("div"); card.className = `pricing-card vip-plan-card ${ plan.highlight ? "vip-highlight" : "" }`; const benefitsList = plan.benefits .map( (benefit) => `${selectedVIPPlan.name}
${selectedVIPPlan.price}
📅 ${selectedVIPPlan.duration}
💰 Economia: ${selectedVIPPlan.savings}
`; confirmBtn.disabled = false; confirmBtn.textContent = translations[currentLanguage]["confirm-vip-subscription"] || "Confirmar Assinatura"; confirmBtn.style.opacity = "1"; confirmBtn.style.cursor = "pointer"; confirmBtn.classList.add("vip-btn"); } else { selectedPackage.innerHTML = `Select a VIP plan above
`; confirmBtn.disabled = true; confirmBtn.textContent = translations[currentLanguage]?.["button-select-vip-plan-first"] || "Select a VIP Plan First"; confirmBtn.style.opacity = "0.5"; confirmBtn.style.cursor = "not-allowed"; confirmBtn.classList.remove("vip-btn"); } } async function sendVIPToWhatsApp() { if (!selectedVIPPlan) { alert(translations[currentLanguage]?.["alert-select-vip-plan"] || "Please select a VIP plan first."); return; } // Obter informações do cliente const customerName = document .getElementById("customerNameVIP") .value.trim(); const customerPhone = document .getElementById("customerPhoneVIP") .value.trim(); const customerEmail = document .getElementById("customerEmailVIP") .value.trim(); if (!customerName || !customerPhone || !customerEmail) { alert(translations[currentLanguage]?.["alert-fill-required-fields"] || "Please fill in all required fields (*)."); return; } // Save user info to file await saveUserInfo(customerName, customerPhone, "vip", { email: customerEmail, plan_name: selectedVIPPlan.name, price: selectedVIPPlan.price, duration: selectedVIPPlan.duration, savings: selectedVIPPlan.savings, }); const messages = { pt: `👑 *ASSINATURA VIP - PLANO ${selectedVIPPlan.name}* 👑 👋 Olá Akemi! Gostaria de assinar o plano VIP: 👤 *Nome:* ${customerName} 📱 *Telefone:* ${customerPhone} 📧 *Email:* ${customerEmail} 💎 *PLANO ESCOLHIDO:* 📋 *Plano:* ${selectedVIPPlan.name} 💰 *Valor:* ${selectedVIPPlan.price} 📅 *Período:* ${selectedVIPPlan.duration} 💵 *Valor Original:* ${selectedVIPPlan.originalPrice} 🎉 *Economia:* ${selectedVIPPlan.savings} 💳 *Chave PIX:* akemisato030@gmail.com 💳 *Forma de Pagamento:* ${ selectedVIPPlan.type === "weekly" ? "Semanal" : selectedVIPPlan.type === "monthly" ? "Mensal" : "Anual" } ⚠️ *IMPORTANTE:* Entendo que a assinatura VIP será ativada apenas após confirmação do pagamento e inclui todos os benefícios descritos no plano escolhido. 🌟 *BENEFÍCIOS INCLUSOS:* • Chamadas de vídeo exclusivas • Packs de fotos e vídeos premium • Peças íntimas usadas • Brinquedos eróticos (planos superiores) • Chat prioritário 24/7 • Conteúdo diário exclusivo • Surpresas regulares Aguardo confirmação para enviar o comprovante e ativar minha assinatura VIP! ✨👑`, en: `👑 *VIP SUBSCRIPTION - ${selectedVIPPlan.name} PLAN* 👑 👋 Hello Akemi! I would like to subscribe to the VIP plan: 👤 *Name:* ${customerName} 📱 *Phone:* ${customerPhone} 📧 *Email:* ${customerEmail} 💎 *CHOSEN PLAN:* 📋 *Plan:* ${selectedVIPPlan.name} 💰 *Price:* ${selectedVIPPlan.price} 📅 *Period:* ${selectedVIPPlan.duration} 💵 *Original Price:* ${selectedVIPPlan.originalPrice} 🎉 *Savings:* ${selectedVIPPlan.savings} 💳 *PIX Key:* akemisato030@gmail.com ⚠️ *IMPORTANT:* I understand that the VIP subscription will be activated only after payment confirmation and includes all benefits described in the chosen plan. I await confirmation to send the receipt and activate my VIP subscription! ✨👑`, es: `👑 *SUSCRIPCIÓN VIP - PLAN ${selectedVIPPlan.name}* 👑 👋 ¡Hola Akemi! Me gustaría suscribirme al plan VIP: 👤 *Nombre:* ${customerName} 📱 *Teléfono:* ${customerPhone} 📧 *Email:* ${customerEmail} 💎 *PLAN ELEGIDO:* 📋 *Plan:* ${selectedVIPPlan.name} 💰 *Precio:* ${selectedVIPPlan.price} 📅 *Período:* ${selectedVIPPlan.duration} 💵 *Precio Original:* ${selectedVIPPlan.originalPrice} 🎉 *Ahorro:* ${selectedVIPPlan.savings} 💳 *Clave PIX:* akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entiendo que la suscripción VIP será activada solo después de la confirmación del pago e incluye todos los beneficios descritos en el plan elegido. ¡Espero confirmación para enviar el comprobante y activar mi suscripción VIP! ✨👑`, fr: `👑 *ABONNEMENT VIP - PLAN ${selectedVIPPlan.name}* 👑 👋 Bonjour Akemi! Je voudrais m'abonner au plan VIP: 👤 *Nom:* ${customerName} 📱 *Téléphone:* ${customerPhone} 📧 *Email:* ${customerEmail} 💎 *PLAN CHOISI:* 📋 *Plan:* ${selectedVIPPlan.name} 💰 *Prix:* ${selectedVIPPlan.price} 📅 *Période:* ${selectedVIPPlan.duration} 💵 *Prix Original:* ${selectedVIPPlan.originalPrice} 🎉 *Économies:* ${selectedVIPPlan.savings} 💳 *Clé PIX:* akemisato030@gmail.com ⚠️ *IMPORTANT:* Je comprends que l'abonnement VIP sera activé uniquement après confirmation du paiement et inclut tous les avantages décrits dans le plan choisi. J'attends la confirmation pour envoyer le reçu et activer mon abonnement VIP! ✨👑`, }; const message = messages[currentLanguage]; const whatsappUrl = `https://wa.me/447848188486?text=${encodeURIComponent( message )}`; window.open(whatsappUrl, "_blank"); closeVIPModal(); } function closeVIPModal() { const modal = document.getElementById("vipModal"); if (modal) { modal.classList.remove("show"); setTimeout(() => { modal.style.setProperty("display", "none", "important"); modal.style.setProperty("visibility", "hidden", "important"); modal.style.setProperty("opacity", "0", "important"); }, 300); } try { triggerBannerFromModal(selectedVIPPlan?.price || null, "vip"); } catch (error) { console.warn("Erro ao acionar banner de pagamento para VIP:", error); } } // Store functions function updateStorePricing() { const storePricingGrid = document.getElementById("storePricingGrid"); if (!storePricingGrid) { return; } try { storePricingGrid.innerHTML = ""; if (!storeItemsData || !storeItemsData[currentLanguage]) { return; } const storeItems = storeItemsData[currentLanguage]; storeItems.forEach((item, index) => { const card = document.createElement("div"); card.className = "pricing-card store-item-card"; card.innerHTML = `${selectedStoreItem.name}
${selectedStoreItem.price}
${selectedStoreItem.category}
${selectedStoreItem.description}
Estado: ${selectedStoreItem.condition}
`; confirmBtn.disabled = false; confirmBtn.textContent = translations[currentLanguage]["confirm-store-order"] || "Confirmar Compra"; confirmBtn.style.opacity = "1"; confirmBtn.style.cursor = "pointer"; } else { selectedPackage.innerHTML = `Select an item above
`; confirmBtn.disabled = true; confirmBtn.textContent = translations[currentLanguage]?.["button-select-item-first"] || "Select an Item First"; confirmBtn.style.opacity = "0.5"; confirmBtn.style.cursor = "not-allowed"; } } async function sendStoreToWhatsApp() { if (!selectedStoreItem) { alert(translations[currentLanguage]?.["alert-select-item"] || "Please select an item first."); return; } // Obter informações do cliente const customerName = document .getElementById("customerNameStore") .value.trim(); const customerPhone = document .getElementById("customerPhoneStore") .value.trim(); const customerEmail = document .getElementById("customerEmailStore") .value.trim(); const customerCPF = document .getElementById("customerCPFStore") .value.trim(); const customerAddress = document .getElementById("customerAddressStore") .value.trim(); const customerCEP = document .getElementById("customerCEPStore") .value.trim(); const customerObservations = document .getElementById("customerObservationsStore") .value.trim(); if ( !customerName || !customerPhone || !customerEmail || !customerCPF || !customerAddress || !customerCEP ) { alert( translations[currentLanguage]?.["alert-fill-required-delivery"] || "Please fill in all required fields (*) for delivery." ); return; } // Save user info to file await saveUserInfo(customerName, customerPhone, "store", { email: customerEmail, cpf: customerCPF, address: customerAddress, cep: customerCEP, item_name: selectedStoreItem.name, price: selectedStoreItem.price, category: selectedStoreItem.category, observations: customerObservations || "None", }); const messages = { pt: `🗡️ *PEDIDO DE PEÇAS USADAS MÍSTICAS* 🗡️ 👋 Olá Akemi! Gostaria de adquirir: 👤 *Nome:* ${customerName} 📱 *Telefone:* ${customerPhone} 📧 *Email:* ${customerEmail} 🆔 *CPF:* ${customerCPF} 👗 *Peça:* ${selectedStoreItem.name} 💰 *Valor:* ${selectedStoreItem.price} 📂 *Categoria:* ${selectedStoreItem.category} 📝 *Descrição:* ${selectedStoreItem.description} 🔍 *Estado:* ${selectedStoreItem.condition} 💳 *Chave PIX:* akemisato030@gmail.com 📍 *ENDEREÇO DE ENTREGA:* ${customerAddress} 📮 *CEP:* ${customerCEP} ${customerObservations ? `📝 *Observações:* ${customerObservations}` : ""} ⏱️ *PRAZO DE ENTREGA:* 15 a 28 dias úteis 📦 *ENVIO:* Discreto via Correios com rastreamento ⚠️ *IMPORTANTE:* Entendo que a peça será enviada discretamente apenas após confirmação do pagamento. Aguardo confirmação para enviar o comprovante! ✨`, en: `🗡️ *MYSTICAL USED ITEMS ORDER* 🗡️ 👋 Hello Akemi! I would like to purchase: 👤 *Name:* ${customerName} 📱 *Phone:* ${customerPhone} 👗 *Item:* ${selectedStoreItem.name} 💰 *Price:* ${selectedStoreItem.price} 📂 *Category:* ${selectedStoreItem.category} 📝 *Description:* ${selectedStoreItem.description} 🔍 *Condition:* ${selectedStoreItem.condition} 💳 *PIX Key:* akemisato030@gmail.com ⚠️ *IMPORTANT:* I understand that the item will be sent discreetly only after payment confirmation. I await confirmation to send the receipt! ✨`, es: `🗡️ *PEDIDO DE PIEZAS USADAS MÍSTICAS* 🗡️ 👋 ¡Hola Akemi! Me gustaría adquirir: 👤 *Nombre:* ${customerName} 📱 *Teléfono:* ${customerPhone} 👗 *Pieza:* ${selectedStoreItem.name} 💰 *Precio:* ${selectedStoreItem.price} 📂 *Categoría:* ${selectedStoreItem.category} 📝 *Descripción:* ${selectedStoreItem.description} 🔍 *Estado:* ${selectedStoreItem.condition} 💳 *Clave PIX:* akemisato030@gmail.com ⚠️ *IMPORTANTE:* Entiendo que la pieza será enviada discretamente solo después de la confirmación del pago. ¡Espero confirmación para enviar el comprobante! ✨`, fr: `🗡️ *COMMANDE PIÈCES USAGÉES MYSTIQUES* 🗡️ 👋 Bonjour Akemi! Je voudrais acquérir: 👤 *Nom:* ${customerName} 📱 *Téléphone:* ${customerPhone} 👗 *Article:* ${selectedStoreItem.name} 💰 *Prix:* ${selectedStoreItem.price} 📂 *Catégorie:* ${selectedStoreItem.category} 📝 *Description:* ${selectedStoreItem.description} 🔍 *État:* ${selectedStoreItem.condition} 💳 *Clé PIX:* akemisato030@gmail.com ⚠️ *IMPORTANT:* Je comprends que l'article sera envoyé discrètement uniquement après confirmation du paiement. J'attends la confirmation pour envoyer le reçu! ✨`, }; const message = messages[currentLanguage]; const whatsappUrl = `https://wa.me/447848188486?text=${encodeURIComponent( message )}`; window.open(whatsappUrl, "_blank"); closeStoreModal(); } function closeStoreModal() { const modal = document.getElementById("storeModal"); if (modal) { modal.classList.remove("show"); setTimeout(() => { modal.style.display = "none"; }, 300); } try { triggerBannerFromModal(selectedStoreItem?.price || null, "store"); } catch (error) { console.warn("Erro ao acionar banner de pagamento para loja:", error); } } // Save file using fetch API async function createFile(filePath, content) { try { const response = await fetch("/create-file", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ filePath, content }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error("Error creating file:", error); throw error; } } // Save user info to file async function saveUserInfo( customerName, customerPhone, type, additionalInfo = {} ) { try { // Ensure user_info directory exists const userInfoDir = "d:/TRABALHOS/Akemi/Sites/Mystic(1)/user_info"; // Sanitize name and phone for filename const sanitizedName = customerName.replace(/[^a-zA-Z0-9]/g, "_"); const sanitizedPhone = customerPhone.replace(/[^0-9]/g, ""); const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); // Create file content const content = { name: customerName, phone: customerPhone, type: type, timestamp: timestamp, ...additionalInfo, }; // Create file with name and phone const fileName = `${sanitizedName}_${sanitizedPhone}.txt`; const filePath = `${userInfoDir}/${fileName}`; // Create file content string const fileContent = Object.entries(content) .map(([key, value]) => `${key}: ${value}`) .join("\n"); // Create file using the createFile function await createFile(filePath, fileContent); console.log("✅ User info saved:", fileName); } catch (error) { console.error("❌ Error saving user info:", error); } } // Function to restore photos for each video container async function restorePhotosForContainer(containerId) { try { // Get the URL pattern based on container ID const baseKey = `photo_${containerId}`; // Try to get stored URL from localStorage const photoUrl = localStorage.getItem(baseKey + "_url"); if (photoUrl) { const container = document.getElementById(containerId); if (container) { // Update the UI for this specific container updatePhotoContainerUI(container, photoUrl); } } } catch (error) { console.error( `❌ Error restoring photos for container ${containerId}:`, error ); } } // Function to restore all photos on page load async function restoreAllPhotos() { try { // Get all video containers const containers = document.querySelectorAll(".video-container"); // Restore photos for each container containers.forEach((container) => { if (container.id) { restorePhotosForContainer(container.id); } }); console.log("✅ All photos restored successfully"); } catch (error) { console.error("❌ Error restoring all photos:", error); } } // Profile photo upload functions function uploadProfilePhoto() { console.log("📸 Upload de foto de perfil solicitado"); const fileInput = document.getElementById("profilePhotoInput"); if (fileInput) { fileInput.click(); } else { console.error("❌ Input de upload de perfil não encontrado"); } } // Function to update photo container UI function updatePhotoContainerUI(container, imageUrl) { // Find or create image preview element let preview = container.querySelector(".photo-preview"); if (!preview) { preview = document.createElement("img"); preview.className = "photo-preview"; container.appendChild(preview); } // Update image and container styles preview.src = imageUrl; preview.style.display = "block"; container.classList.add("has-photo"); // Update container background and styles container.style.background = `linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url(${imageUrl})`; container.style.backgroundSize = "cover"; container.style.backgroundPosition = "center"; } async function handleProfilePhotoUpload(input, containerId) { console.log("📁 Processando upload de foto de perfil"); try { if (!window.supabaseClient) { throw new Error( "Supabase client não inicializado. Por favor, recarregue a página." ); } const file = input.files[0]; if (!file) { console.log("❌ Nenhum arquivo selecionado"); return; } // Verificar se é uma imagem if (!file.type.startsWith("image/")) { alert( "⚠️ Por favor, selecione apenas arquivos de imagem!\n\nFormatos aceitos: JPG, PNG, WEBP" ); return; } // Verificar tamanho (máximo 5MB) if (file.size > 5 * 1024 * 1024) { alert( "⚠️ Imagem muito grande!\n\nTamanho máximo: 5MB\nTamanho atual: " + (file.size / (1024 * 1024)).toFixed(2) + "MB" ); return; } console.log( "✅ Arquivo válido:", file.name, "(" + (file.size / 1024).toFixed(1) + " KB)" ); // Criar nome único para o arquivo const timestamp = new Date().getTime(); const fileExt = file.name.split(".").pop(); const fileName = `profile_${timestamp}.${fileExt}`; // Upload para o Supabase console.log("🔄 Fazendo upload para Supabase..."); const { data, error } = await window.supabaseClient.storage .from("videos") .upload(`pfp/${fileName}`, file, { cacheControl: "3600", upsert: true, }); if (error) { console.error("❌ Erro no upload:", error); alert("Erro ao fazer upload da foto. Tente novamente."); return; } // Obter URL pública const { data: urlData } = window.supabaseClient.storage .from("videos") .getPublicUrl(`pfp/${fileName}`); if (!urlData?.publicUrl) { throw new Error("Não foi possível obter URL pública"); } // Save URL in localStorage with container ID if (containerId) { localStorage.setItem(`photo_${containerId}_url`, urlData.publicUrl); // Update the container's UI const container = document.getElementById(containerId); if (container) { updatePhotoContainerUI(container, urlData.publicUrl); } } console.log("🎉 Foto atualizada com sucesso!"); showProfileUploadFeedback(file.name); } catch (error) { console.error("❌ Erro ao processar foto:", error); alert("Erro ao processar foto. Tente novamente."); } } // Função para atualizar interface da foto de perfil function updateProfilePhotoUI(imageUrl) { const placeholder = document.getElementById("uploadPlaceholder"); const preview = document.getElementById("profilePreview"); const overlay = document.getElementById("uploadOverlay"); const circle = document.querySelector(".profile-circle"); if (placeholder && preview && overlay && circle) { // Esconder placeholder placeholder.style.display = "none"; // Mostrar imagem preview.src = imageUrl; preview.style.display = "block"; // Configurar overlay para hover circle.onmouseover = function () { this.style.transform = "scale(1.05)"; this.style.boxShadow = "0 0 30px rgba(220, 20, 60, 0.5)"; overlay.style.display = "flex"; }; circle.onmouseout = function () { this.style.transform = "scale(1)"; this.style.boxShadow = "0 0 20px rgba(220, 20, 60, 0.3)"; overlay.style.display = "none"; }; // Mudar borda para sólida circle.style.border = "3px solid #dc143c"; circle.style.background = "transparent"; } } // Função para restaurar foto de perfil async function restoreProfilePhoto() { try { // Fetch the most recent image from the Supabase bucket const { data, error } = await supabaseClient.storage .from("videos") .list("pfp", { sortBy: { column: "created_at", order: "desc" }, limit: 1, }); if (error) { console.error("❌ Error fetching profile photo:", error); return; } if (!data || data.length === 0) { console.log("No profile photos found in the bucket."); return; } const mostRecentFile = data[0]; const { data: publicUrlData } = supabaseClient.storage .from("videos") .getPublicUrl(`pfp/${mostRecentFile.name}`); if (publicUrlData?.publicUrl) { // Update the profile photo UI updateProfilePhotoUI(publicUrlData.publicUrl); console.log( "✅ Profile photo restored successfully:", publicUrlData.publicUrl ); } } catch (error) { console.error("❌ Error restoring profile photo:", error); } } function showProfileUploadFeedback(fileName) { // Criar notificação temporária const notification = document.createElement("div"); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: linear-gradient(45deg, #dc143c, #8b0000); color: white; padding: 15px 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(220, 20, 60, 0.4); z-index: 9999; font-family: 'Montserrat', sans-serif; font-weight: bold; font-size: 0.9rem; border: 2px solid #dc143c; animation: slideInRight 0.3s ease-out; `; notification.innerHTML = `