diff --git a/app.js b/app.js index f3c9ea7..e902208 100644 --- a/app.js +++ b/app.js @@ -1,60 +1,79 @@ -// Google Opal AI - iOS Studio & 3D Poster Lab Engine +// Google Opal AI - Master Mini-App Studio & 3D Poster Lab Engine v5.0 document.addEventListener('DOMContentLoaded', () => { initNavigation(); initSettings(); initPosterLab(); + initMiniAppsHub(); + initMiniAppBuilder(); initInboxAI(); initHistory(); }); -// --- 1. Tab Navigation --- -function initNavigation() { +// --- Global Navigation --- +window.switchToTab = function(tabId) { const navItems = document.querySelectorAll('.nav-item'); const tabPages = document.querySelectorAll('.tab-page'); + navItems.forEach(n => { + if (n.getAttribute('data-tab') === tabId) { + n.classList.add('active'); + } else { + n.classList.remove('active'); + } + }); + + tabPages.forEach(p => { + if (p.id === tabId) { + p.classList.add('active'); + } else { + p.classList.remove('active'); + } + }); + + window.scrollTo({ top: 0, behavior: 'smooth' }); +}; + +function initNavigation() { + const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', () => { const targetTabId = item.getAttribute('data-tab'); - - navItems.forEach(n => n.classList.remove('active')); - tabPages.forEach(p => p.classList.remove('active')); - - item.classList.add('active'); - const targetPage = document.getElementById(targetTabId); - if (targetPage) targetPage.classList.add('active'); - window.scrollTo({ top: 0, behavior: 'smooth' }); + switchToTab(targetTabId); }); }); // Language Toggle const langBtn = document.getElementById('langToggleBtn'); let currentLang = 'BN'; - langBtn.addEventListener('click', () => { - currentLang = currentLang === 'BN' ? 'EN' : 'BN'; - langBtn.textContent = currentLang === 'BN' ? '🌐 āĻŦāĻžāĻ‚' : '🌐 EN'; - }); -} - -// Global App Switcher -window.openAppRunner = function(appType) { - if (appType === 'inbox_ai') { - document.querySelector('.nav-item[data-tab="tabInboxAI"]').click(); - } else { - document.querySelector('.nav-item[data-tab="tabPosterLab"]').click(); + if (langBtn) { + langBtn.addEventListener('click', () => { + currentLang = currentLang === 'BN' ? 'EN' : 'BN'; + langBtn.textContent = currentLang === 'BN' ? '🌐 āĻŦāĻžāĻ‚' : '🌐 EN'; + }); } -}; +} window.copyText = function(elementId) { const el = document.getElementById(elementId); - if (el && el.textContent) { - navigator.clipboard.writeText(el.textContent).then(() => { + if (el) { + const text = el.value || el.textContent || ''; + navigator.clipboard.writeText(text).then(() => { + alert('✅ Copied to Clipboard!'); + }).catch(() => { + // Fallback + const ta = document.createElement('textarea'); + ta.value = text; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); alert('✅ Copied to Clipboard!'); }); } }; -// --- 2. Settings & Gemini/Gemma API --- +// --- Settings & Gemini 2.0 API Engine --- function initSettings() { const apiKeyInput = document.getElementById('apiKeyInput'); const modelSelect = document.getElementById('modelSelect'); @@ -64,47 +83,54 @@ function initSettings() { // Load saved settings const savedKey = localStorage.getItem('opal_gemini_api_key') || ''; - const savedModel = localStorage.getItem('opal_selected_model') || 'gemini-3.6-flash'; + const savedModel = localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; const savedN8n = localStorage.getItem('opal_n8n_webhook') || 'https://n8n.auraajenticai.cloud/webhook/gt-auto-post'; - apiKeyInput.value = savedKey; - modelSelect.value = savedModel; + + if (apiKeyInput) apiKeyInput.value = savedKey; + if (modelSelect) modelSelect.value = savedModel; if (n8nWebhookInput) n8nWebhookInput.value = savedN8n; - saveBtn.addEventListener('click', async () => { - const key = apiKeyInput.value.trim(); - const model = modelSelect.value; - const n8nUrl = n8nWebhookInput ? n8nWebhookInput.value.trim() : ''; + if (saveBtn) { + saveBtn.addEventListener('click', async () => { + const key = apiKeyInput.value.trim(); + const model = modelSelect.value; + const n8nUrl = n8nWebhookInput ? n8nWebhookInput.value.trim() : ''; - if (n8nUrl) { - localStorage.setItem('opal_n8n_webhook', n8nUrl); - } - - if (!key) { - alert('Settings saved!'); - return; - } - - statusMsg.classList.remove('hidden'); - statusMsg.style.color = '#F472B6'; - statusMsg.textContent = 'âŗ Testing AI connection with Google...'; - - try { - const res = await callGeminiApi(key, model, "Respond with: 'Opal AI Connected successfully!'"); - if (res) { - localStorage.setItem('opal_gemini_api_key', key); - localStorage.setItem('opal_selected_model', model); - statusMsg.style.color = '#10B981'; - statusMsg.textContent = `✅ Settings Saved & Verified: ${res.trim()}`; + if (n8nUrl) { + localStorage.setItem('opal_n8n_webhook', n8nUrl); } - } catch (e) { - statusMsg.style.color = '#EF4444'; - statusMsg.textContent = `❌ Error: ${e.message}`; - } - }); + + if (!key) { + localStorage.setItem('opal_selected_model', model); + statusMsg.classList.remove('hidden'); + statusMsg.style.color = '#10B981'; + statusMsg.textContent = '✅ Settings saved (Offline templates active).'; + return; + } + + statusMsg.classList.remove('hidden'); + statusMsg.style.color = '#F472B6'; + statusMsg.textContent = 'âŗ Testing Gemini 2.0 AI connection with Google...'; + + try { + const res = await callGeminiApi(key, model, "Respond with: 'Google Opal AI Connected successfully!'"); + if (res) { + localStorage.setItem('opal_gemini_api_key', key); + localStorage.setItem('opal_selected_model', model); + statusMsg.style.color = '#10B981'; + statusMsg.textContent = `✅ Verified & Active: ${res.trim()}`; + } + } catch (e) { + statusMsg.style.color = '#EF4444'; + statusMsg.textContent = `❌ Connection Error: ${e.message}`; + } + }); + } } async function callGeminiApi(apiKey, model, prompt) { - const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`; + const activeModel = model || localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; + const url = `https://generativelanguage.googleapis.com/v1beta/models/${activeModel}:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: prompt }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 2048 } @@ -117,7 +143,7 @@ async function callGeminiApi(apiKey, model, prompt) { }); if (!response.ok) { - const errData = await response.json(); + const errData = await response.json().catch(() => ({})); throw new Error(errData?.error?.message || `HTTP ${response.status}`); } @@ -125,10 +151,463 @@ async function callGeminiApi(apiKey, model, prompt) { return data?.candidates?.[0]?.content?.parts?.[0]?.text || ''; } -// --- 3. 3D Poster Lab Engine (True 3D Dual-Tier Gold Podium) --- +// --- Curated Pre-Built Mini-Apps Suite --- +const PREBUILT_MINI_APPS = [ + { + id: 'gt_studio', + name: '3D Commercial Poster Lab', + emoji: '🎨', + category: 'ecommerce', + badge: 'GEM', + desc: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻ›āĻŦāĻŋ, ā§ŠāĻĄāĻŋ āĻŽāĻžāĻ°ā§āĻŦ⧇āϞ āĻ¸ā§āĻŸā§‡āϜ āĻ“ WhatsApp QR āϏāĻš 4K āĻĢ⧇āϏāĻŦ⧁āĻ• āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāύ āĻĒā§‹āĻ¸ā§āϟāĻžāϰ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', + steps: '7 Steps â€ĸ 3D Canvas', + isPosterLab: true + }, + { + id: 'inbox_ai', + name: 'Customer Care & Sales Auto-Reply', + emoji: 'đŸ’Ŧ', + category: 'sales', + badge: 'AI', + desc: 'āĻĢ⧇āϏāĻŦ⧁āĻ• āĻ“ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇āϰ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĒā§āϰāĻļā§āύ⧇āϰ ā§ŠāϟāĻŋ āχāύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŽāĻŋāĻˇā§āϟāĻŋ āĻ“ āϏ⧇āϞāϏ āĻ•ā§āϞ⧋āϜāĻŋāĻ‚ āωāĻ¤ā§āϤāϰ āĻŦāĻžāύāĻžā§ŸāĨ¤', + steps: '3 Steps â€ĸ Sales Closer', + fields: [ + { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ āĻŽā§‡āϏ⧇āϜ (Customer Message)', placeholder: 'e.g. āφāĻĒāύāĻžāĻĻ⧇āϰ āϏāĻŋāϰāĻžāĻŽā§‡āϰ āĻĻāĻžāĻŽ āĻ•āϤ āφāϰ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āϚāĻžāĻ°ā§āϜ āĻ•āϤ?' }, + { id: 'field2', label: 'āĻĻā§‹āĻ•āĻžāύ⧇āϰ āĻ…āĻĢāĻžāϰ āĻŦāĻž āĻšāϟāϞāĻžāχāύ (Store Context)', placeholder: 'e.g. āĻĻāĻžāĻŽ ā§§ā§Ļā§Ŧā§Ļ āϟāĻžāĻ•āĻž, āĻĸāĻžāĻ•āĻž ā§­ā§Ļ āϟāĻžāĻ•āĻž, āĻšāϟāϞāĻžāχāύ ā§Ļ⧧⧭⧧⧍-ā§Ē⧍ā§Ŧā§Žā§­ā§§' } + ], + promptTemplate: `You are an expert Bangladeshi e-commerce sales closer. +Customer message: {{field1}} +Store context: {{field2}} + +Write 3 distinct ready-to-copy Bengali replies: +1. Instant sweet greeting with price & benefits +2. Direct order closing script asking for Name, Address, Phone +3. 1-Click WhatsApp direct order message with link https://wa.me/8801712426871` + }, + { + id: 'veo_prompter', + name: 'Google Veo 3.1 Video Ad Prompter', + emoji: 'đŸŽŦ', + category: 'social', + badge: 'VEO 3.1', + desc: 'āϗ⧁āĻ—āϞ Veo ā§Š.ā§§ āĻ“ Sora-āϰ āϜāĻ¨ā§āϝ āϏāĻŋāύ⧇āĻŽāĻžāϟāĻŋāĻ• 9:16 āĻ­āĻŋāĻĄāĻŋāĻ“ āĻĒā§āϰāĻŽā§āĻĒāϟ, āĻ•ā§āϝāĻžāĻŽā§‡āϰāĻž āĻŽā§‹āĻļāύ āĻ“ āϞāĻžāχāϟāĻŋāĻ‚ āĻ—āĻžāχāĻĄ āĻŦāĻžāύāĻžā§ŸāĨ¤', + steps: '4 Steps â€ĸ AI Video', + fields: [ + { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āύāĻžāĻŽ āĻ“ āϧāϰāĻŖ (Product)', placeholder: 'e.g. Medicube Collagen Jelly Cream' }, + { id: 'field2', label: 'āĻ­āĻŋāĻĄāĻŋāĻ“āϰ āĻ­āĻžāχāĻŦ āĻ“ āĻ¸ā§āϟāĻžāχāϞ (Style/Vibe)', placeholder: 'e.g. Luxury Korean Aesthetic Glow, Neon reflections, 4k macro' } + ], + promptTemplate: `You are a world-class AI Video Prompt Engineer for Google Veo 3.1 and Sora. +Create an ultra-detailed, cinematic 9:16 vertical video prompt for: +Product: {{field1}} +Style/Vibe: {{field2}} + +Include: +1. Master Cinematic Prompt (in English for AI video model) +2. Camera Movements (Macro close-up, 360 rotation, slow motion drop) +3. Studio Lighting & Physics (Softbox, caustics, rim light) +4. Bengali Narration / Voiceover Script (15 seconds)` + }, + { + id: 'risk_scorer', + name: 'Gemini COD Fraud & Return Risk Shield', + emoji: 'đŸ›Ąī¸', + category: 'tools', + badge: 'AI SHIELD', + desc: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĢā§‹āύ āύāĻžāĻŽā§āĻŦāĻžāϰ, āĻ āĻŋāĻ•āĻžāύāĻž āĻ“ āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻ•āϰ⧇ āϰāĻŋāϟāĻžāĻ°ā§āύ āĻĢā§āϰāĻĄ āϰāĻŋāĻ¸ā§āĻ• āĻ¸ā§āϕ⧋āϰ āĻĻā§‡ā§ŸāĨ¤', + steps: 'Real-time â€ĸ Gemini 2.0', + fields: [ + { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĢā§‹āύ āύāĻžāĻŽā§āĻŦāĻžāϰ (Phone Number)', placeholder: 'e.g. 01819998877' }, + { id: 'field2', label: 'āĻ āĻŋāĻ•āĻžāύāĻž āĻ“ āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻŽā§‚āĻ˛ā§āϝ (Address & Amount)', placeholder: 'e.g. Mirpur 10, Dhaka - Amount: ā§ŗ 3,200' } + ], + promptTemplate: `You are an advanced e-commerce Fraud Risk Analysis Engine for Bangladesh logistics. +Phone: {{field1}} +Order Info: {{field2}} + +Evaluate: +1. Risk Level: (LOW / MEDIUM / HIGH) +2. Recommendation: (Proceed with COD / Take Advance Delivery Charge ā§ŗ150 / Call to verify) +3. Short reasoning in clear Bengali.` + }, + { + id: 'ecommerce_launch', + name: 'E-Commerce Viral Product Launch Kit', + emoji: 'đŸ›ī¸', + category: 'ecommerce', + badge: 'VIRAL', + desc: 'āϝ⧇āϕ⧋āύ⧋ āĻĒāĻŖā§āϝ⧇āϰ āφāĻ•āĻ°ā§āώāĻŖā§€ā§Ÿ āĻĢ⧇āϏāĻŦ⧁āĻ• āĻĒā§‹āĻ¸ā§āϟ āĻ•ā§āϝāĻžāĻĒāĻļāύ, āĻĒ⧇āχāύ āĻĒā§Ÿā§‡āĻ¨ā§āϟ āĻšā§āĻ• āĻ“ āĻ…āĻĢāĻžāϰ āĻ•āĻĒāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', + steps: '5 Steps â€ĸ Marketing', + fields: [ + { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āύāĻžāĻŽ āĻ“ āĻ•ā§āϝāĻžāϟāĻžāĻ—āϰāĻŋ (Product Name)', placeholder: 'e.g. Korean Snail Mucin Power Essence' }, + { id: 'field2', label: 'āĻŽā§‚āϞ āϏ⧁āĻŦāĻŋāϧāĻž āĻ“ āĻ…āĻĢāĻžāϰ (Key Benefits & Price)', placeholder: 'e.g. āĻŦā§āϰāϪ⧇āϰ āĻĻāĻžāĻ— āĻĻā§‚āϰ āĻ•āϰ⧇, āĻĄāĻŋāĻĒ āĻŽā§Ÿā§‡āĻļā§āϚāĻžāϰāĻžāχāϜāĻŋāĻ‚, āĻĻāĻžāĻŽ ā§ŗā§§,ā§Ēā§Ģā§Ļ (āĻ…āĻĢāĻžāϰ ⧍ā§Ģ% āĻ›āĻžā§œ)' } + ], + promptTemplate: `You are a high-converting Facebook ad copywriter in Bangladesh. +Create a complete viral product launch post in attractive Bengali for: +Product: {{field1}} +Benefits & Offer: {{field2}} + +Format: +- 3 Viral Opening Hooks (Emoji heavy) +- Problem & Solution story +- Special Limited Time Offer & Delivery Info +- Urgent Call-to-Action with WhatsApp & Website link` + }, + { + id: 'tiktok_hooks', + name: 'TikTok & Meta Reels Viral Hook Matrix', + emoji: 'đŸ”Ĩ', + category: 'social', + badge: 'HOOKS', + desc: 'āĻĒā§āϰāĻĨāĻŽ ā§Š āϏ⧇āϕ⧇āĻ¨ā§āĻĄā§‡ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻšā§‹āĻ– āφāϟāϕ⧇ āĻĢ⧇āϞāĻžāϰ āĻŽāϤ⧋ ā§ĢāϟāĻŋ āϏāĻžāχāϕ⧋āϞāϜāĻŋāĻ•ā§āϝāĻžāϞ āĻ­āĻžāχāϰāĻžāϞ āĻšā§āĻ• āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', + steps: '5 Viral Hooks â€ĸ Reels', + fields: [ + { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟ āĻŦāĻž āĻŦāĻŋāĻˇā§Ÿā§‡āϰ āύāĻžāĻŽ (Product / Topic)', placeholder: 'e.g. Korean Glass Skin Facial Foam' }, + { id: 'field2', label: 'āϟāĻžāĻ°ā§āϗ⧇āϟ āĻ…āĻĄāĻŋā§Ÿā§‡āĻ¨ā§āϏ (Target Audience)', placeholder: 'e.g. āϝāĻžāĻĻ⧇āϰ āĻŽā§āϖ⧇ āϰ⧋āĻĻ⧇ āĻĒā§‹ā§œāĻž āĻĻāĻžāĻ— āĻ“ āĻŦā§āϰāϪ⧇āϰ āϏāĻŽāĻ¸ā§āϝāĻž āĻ°ā§Ÿā§‡āϛ⧇' } + ], + promptTemplate: `You are a viral TikTok & Instagram Reels growth strategist. +Create 5 powerful 3-second visual + verbal hooks in Bengali for: +Product: {{field1}} +Target Audience: {{field2}} + +Format each hook with: +- Visual Action (Screen text & actor action) +- Spoken Audio Hook (High curiosity / urgency) +- Psychology trigger explanation` + }, + { + id: 'urgency_sales', + name: 'Flash Sale & Urgency Campaign Copywriter', + emoji: 'đŸˇī¸', + category: 'sales', + badge: 'OFFER', + desc: '⧍ā§Ē āϘāĻŖā§āϟāĻžāϰ āĻĢā§āĻ˛ā§āϝāĻžāĻļ āϏ⧇āϞ, āĻ¸ā§āϟāĻ• āĻ•ā§āϞāĻŋ⧟āĻžāϰ⧇āĻ¨ā§āϏ āĻ“ āψāĻĻ/āĻŦ⧈āĻļāĻžāĻ–ā§€ āĻ…āĻĢāĻžāϰ⧇āϰ āĻšāĻžāχ-āĻ•āύāĻ­āĻžāĻ°ā§āϟāĻŋāĻ‚ āĻ•āĻĒāĻŋ āĻŦāĻžāύāĻžā§ŸāĨ¤', + steps: 'Flash Sales â€ĸ Copy', + fields: [ + { id: 'field1', label: 'āĻ…āĻĢāĻžāϰ⧇āϰ āύāĻžāĻŽ āĻ“ āĻĄāĻŋāϏāĻ•āĻžāωāĻ¨ā§āϟ (Offer Details)', placeholder: 'e.g. 48 Hours Weekend Flash Sale - Flat 35% OFF' }, + { id: 'field2', label: 'āĻļāĻ°ā§āϤ āĻ“ āĻĢā§āϰāĻŋ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ (Conditions & Perks)', placeholder: 'e.g. āĻĒā§āϰāĻĨāĻŽ ā§Ģā§Ļ āϜāύ⧇āϰ āϜāĻ¨ā§āϝ āĻĢā§āϰāĻŋ āĻ—āĻŋāĻĢāϟ āĻ“ āĻĢā§āϰāĻŋ āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ' } + ], + promptTemplate: `Create an irresistible, high-urgency Flash Sale ad copy in natural Bengali for: +Campaign: {{field1}} +Perks: {{field2}} + +Include FOMO triggers, countdown psychological anchors, and clear WhatsApp booking steps.` + }, + { + id: 'courier_formatter', + name: 'Steadfast & Pathao Consignment Formatter', + emoji: 'đŸ“Ļ', + category: 'tools', + badge: 'LOGISTICS', + desc: 'āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻŸā§‡āĻ•ā§āϏāϟ āĻĨ⧇āϕ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ āϕ⧁āϰāĻŋ⧟āĻžāϰ āĻāĻ¨ā§āĻŸā§āϰāĻŋ āĻĢāϰāĻŽā§āϝāĻžāϟ āĻ“ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āϞ⧇āĻŦ⧇āϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', + steps: '1-Click â€ĸ Logistics', + fields: [ + { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻŸā§‡āĻ•ā§āϏāϟ (Order Text)', placeholder: 'e.g. āύāĻžāĻŽ: āϤāĻžāύāĻ­ā§€āϰ āĻšāĻžāϏāĻžāύ, āĻĢā§‹āύ: 01712345678, āĻ āĻŋāĻ•āĻžāύāĻž: āĻŦāĻžā§œāĻŋ ⧧⧍, āϰ⧋āĻĄ ā§Ģ, āϧāĻžāύāĻŽāĻ¨ā§āĻĄāĻŋ, āĻĸāĻžāĻ•āĻžāĨ¤ āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟ: ā§§ āĻĒāĻŋāϏ āϏāĻŋāϰāĻžāĻŽ (ā§ŗā§§ā§Ļā§Ŧā§Ļ)' }, + { id: 'field2', label: 'āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āϚāĻžāĻ°ā§āϜ āĻ“ āύ⧋āϟ (COD & Notes)', placeholder: 'e.g. COD Amount: ā§ŗ 1130 (Dhaka inside ā§ŗ70)' } + ], + promptTemplate: `Parse this customer order and structure it cleanly for Steadfast / Pathao Courier API and Print Packing Sticker: +Order Text: {{field1}} +COD Info: {{field2}} + +Generate: +1. Structured CSV/JSON Format (Name, Phone, Address, COD, Instruction) +2. Clean Printable Packing Slip in Bengali.` + } +]; + +// --- Mini-Apps Hub Logic --- +let activeCategory = 'all'; + +function initMiniAppsHub() { + renderMiniApps(); + + const filterChips = document.querySelectorAll('.filter-chip'); + filterChips.forEach(chip => { + chip.addEventListener('click', () => { + filterChips.forEach(c => c.classList.remove('active')); + chip.classList.add('active'); + activeCategory = chip.getAttribute('data-cat'); + renderMiniApps(); + }); + }); +} + +function getCustomMiniApps() { + return JSON.parse(localStorage.getItem('opal_custom_apps') || '[]'); +} + +function renderMiniApps() { + const container = document.getElementById('appsGridContainer'); + if (!container) return; + + const customApps = getCustomMiniApps(); + const allApps = [...PREBUILT_MINI_APPS, ...customApps]; + + const filtered = activeCategory === 'all' + ? allApps + : (activeCategory === 'custom' ? customApps : allApps.filter(a => a.category === activeCategory)); + + if (filtered.length === 0) { + container.innerHTML = ` +
+ 📭 +

No mini-apps found in this category. Click "+ Create App" to build one!

+
+ `; + return; + } + + container.innerHTML = filtered.map(app => ` +
+
+
${app.emoji || '💎'}
+ ${app.badge || 'CUSTOM'} +
+
+

${app.name}

+

${app.desc || 'AI powered dynamic mini-app for client dashboard.'}

+
+ +
+ `).join(''); +} + +// --- Visual Mini-App Builder --- +function initMiniAppBuilder() { + const nameInput = document.getElementById('builderAppName'); + const emojiInput = document.getElementById('builderAppEmoji'); + const catSelect = document.getElementById('builderCategory'); + const modelSelect = document.getElementById('builderModel'); + const descInput = document.getElementById('builderDesc'); + const f1Input = document.getElementById('builderField1'); + const f2Input = document.getElementById('builderField2'); + const templateInput = document.getElementById('builderPromptTemplate'); + const saveBtn = document.getElementById('saveMiniAppBtn'); + const testBtn = document.getElementById('testMiniAppBtn'); + const statusMsg = document.getElementById('builderStatusMsg'); + + if (!saveBtn) return; + + saveBtn.addEventListener('click', () => { + const name = nameInput.value.trim(); + if (!name) { + alert('Please enter a Mini-App name'); + return; + } + + const newApp = { + id: 'custom_' + Date.now(), + name: name, + emoji: emojiInput.value.trim() || '💎', + category: catSelect.value, + model: modelSelect.value, + badge: 'CUSTOM APP', + desc: descInput.value.trim() || 'Custom client dashboard mini-app.', + steps: 'Custom â€ĸ Gemini AI', + fields: [ + { id: 'field1', label: f1Input.value.trim() || 'Field 1', placeholder: 'Enter ' + (f1Input.value.trim() || 'Field 1') }, + { id: 'field2', label: f2Input.value.trim() || 'Field 2', placeholder: 'Enter ' + (f2Input.value.trim() || 'Field 2') } + ], + promptTemplate: templateInput.value.trim(), + createdAt: new Date().toISOString() + }; + + const existing = getCustomMiniApps(); + existing.unshift(newApp); + localStorage.setItem('opal_custom_apps', JSON.stringify(existing)); + + statusMsg.classList.remove('hidden'); + statusMsg.style.color = '#10B981'; + statusMsg.textContent = `🎉 Mini-App "${name}" successfully saved & added to Hub!`; + + renderMiniApps(); + setTimeout(() => { + switchToTab('tabApps'); + statusMsg.classList.add('hidden'); + }, 1200); + }); + + if (testBtn) { + testBtn.addEventListener('click', () => { + const name = nameInput.value.trim() || 'Test Mini-App'; + const tempApp = { + id: 'test_temp', + name: name, + emoji: emojiInput.value.trim() || 'đŸ§Ē', + desc: descInput.value.trim() || 'Testing custom app runner', + fields: [ + { id: 'field1', label: f1Input.value.trim() || 'Field 1', placeholder: 'Input 1' }, + { id: 'field2', label: f2Input.value.trim() || 'Field 2', placeholder: 'Input 2' } + ], + promptTemplate: templateInput.value.trim(), + model: modelSelect.value + }; + launchRunnerWithApp(tempApp); + }); + } +} + +// --- Interactive Mini-App Runner (Modal) --- +let currentRunningApp = null; + +window.openAppRunner = function(appId) { + if (appId === 'gt_studio') { + switchToTab('tabPosterLab'); + return; + } + if (appId === 'inbox_ai') { + switchToTab('tabInboxAI'); + return; + } + + const allApps = [...PREBUILT_MINI_APPS, ...getCustomMiniApps()]; + const app = allApps.find(a => a.id === appId); + if (!app) return; + + launchRunnerWithApp(app); +}; + +function launchRunnerWithApp(app) { + currentRunningApp = app; + const modal = document.getElementById('appRunnerModal'); + const title = document.getElementById('runnerModalTitle'); + const desc = document.getElementById('runnerModalDesc'); + const formBox = document.getElementById('runnerDynamicForm'); + const resultBox = document.getElementById('runnerResultBox'); + const statusMsg = document.getElementById('runnerStatusMsg'); + + title.innerHTML = `${app.emoji || '🚀'} ${app.name}`; + desc.textContent = app.desc || ''; + resultBox.classList.add('hidden'); + statusMsg.classList.add('hidden'); + + const fields = app.fields || [ + { id: 'field1', label: 'Input 1', placeholder: 'Enter details...' }, + { id: 'field2', label: 'Input 2', placeholder: 'Enter additional context...' } + ]; + + formBox.innerHTML = fields.map((f, i) => ` +
+ + +
+ `).join(''); + + modal.classList.remove('hidden'); +} + +window.closeAppRunner = function() { + document.getElementById('appRunnerModal').classList.add('hidden'); + currentRunningApp = null; +}; + +// Handle Mini-App Execution +document.addEventListener('DOMContentLoaded', () => { + const execBtn = document.getElementById('runnerExecuteBtn'); + if (execBtn) { + execBtn.addEventListener('click', async () => { + if (!currentRunningApp) return; + + const statusMsg = document.getElementById('runnerStatusMsg'); + const resultBox = document.getElementById('runnerResultBox'); + const resultContent = document.getElementById('runnerResultContent'); + + statusMsg.classList.remove('hidden'); + statusMsg.style.color = '#C084FC'; + statusMsg.textContent = 'âŗ Processing with Google Gemini 2.0 AI...'; + execBtn.disabled = true; + + // Extract form values + const inputs = document.querySelectorAll('.runner-input'); + let prompt = currentRunningApp.promptTemplate || 'Generate helpful response for the user.'; + + inputs.forEach(input => { + const varName = input.getAttribute('data-var'); + const val = input.value.trim() || 'N/A'; + const regex = new RegExp(`{{${varName}}}`, 'g'); + prompt = prompt.replace(regex, val); + }); + + const apiKey = localStorage.getItem('opal_gemini_api_key') || ''; + const model = currentRunningApp.model || localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; + + try { + let output = ''; + if (apiKey) { + output = await callGeminiApi(apiKey, model, prompt); + } else { + // Dynamic intelligent fallback + output = `✨ [Google Opal AI Offline Mode]\n\n` + + `Generated Output for: ${currentRunningApp.name}\n` + + `----------------------------------------\n` + + `ā§§. āĻ…āĻĢāĻžāϰ āĻ“ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ āϰ⧇āϏāĻĒāĻ¨ā§āϏ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤\n` + + `⧍. ā§§ā§Ļā§Ļ% āĻœā§‡āύ⧁āχāύ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āĻ“ āϏ⧁āĻĒāĻžāϰāĻĢāĻžāĻ¸ā§āϟ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύāĨ¤\n` + + `ā§Š. āϏāϰāĻžāϏāϰāĻŋ āϝ⧋āĻ—āĻžāϝ⧋āĻ—: https://wa.me/8801712426871\n\n` + + `💡 āϟāĻŋāĻĒāϏ: Settings-āĻ āĻ—āĻŋā§Ÿā§‡ āφāĻĒāύāĻžāϰ Google Gemini API Key āĻŦāϏāĻžāϞ⧇ āϰāĻŋā§Ÿā§‡āϞ-āϟāĻžāχāĻŽ āφāύāϞāĻŋāĻŽāĻŋāĻŸā§‡āĻĄ āϞāĻžāχāĻ­ āϰ⧇āϏāĻĒāĻ¨ā§āϏ āĻĒāĻžāĻŦ⧇āύ!`; + } + + resultContent.textContent = output.trim(); + resultBox.classList.remove('hidden'); + statusMsg.classList.add('hidden'); + + // Save to History + saveGenerationToHistory({ + type: currentRunningApp.name, + title: currentRunningApp.name, + price: 'AI Generation', + date: new Date().toLocaleTimeString() + }); + + } catch (err) { + statusMsg.style.color = '#EF4444'; + statusMsg.textContent = `❌ Error: ${err.message}`; + } + + execBtn.disabled = false; + }); + } +}); + +// --- 1-Click Client Dashboard Embed Modal --- +window.openEmbedModal = function(appId) { + const modal = document.getElementById('embedModal'); + const title = document.getElementById('embedModalTitle'); + const iframeBox = document.getElementById('embedIframeCode'); + const apiUrlBox = document.getElementById('embedApiUrl'); + + const allApps = [...PREBUILT_MINI_APPS, ...getCustomMiniApps()]; + const app = allApps.find(a => a.id === appId) || { name: 'Opal Mini-App', id: appId }; + + title.innerHTML = `đŸ“Ļ Embed "${app.name}" in Client Dashboard`; + + const baseUrl = 'https://opal.auraajenticai.cloud'; + iframeBox.textContent = ``; + apiUrlBox.textContent = `${baseUrl}/api/v1/mini-app/run?app_id=${app.id}`; + + modal.classList.remove('hidden'); +}; + +window.closeEmbedModal = function() { + document.getElementById('embedModal').classList.add('hidden'); +}; + +// --- Masterpiece 3D Canvas Poster Engine --- +let selectedStageTheme = 'obsidian_gold'; + function initPosterLab() { const productInput = document.getElementById('productInput'); const productPrice = document.getElementById('productPrice'); + const customBadgeInput = document.getElementById('customBadgeInput'); + const aspectRatioSelect = document.getElementById('aspectRatioSelect'); + const brandSelect = document.getElementById('brandWatermarkSelect'); const photoFileInput = document.getElementById('photoFileInput'); const clearPhotoBtn = document.getElementById('clearPhotoBtn'); const photoPreviewContainer = document.getElementById('photoPreviewContainer'); @@ -137,9 +616,20 @@ function initPosterLab() { const posterStatusText = document.getElementById('posterStatusText'); const posterResultCard = document.getElementById('posterResultCard'); const posterCanvas = document.getElementById('posterCanvas'); + const canvasContainer = document.getElementById('canvasContainer'); const downloadPosterBtn = document.getElementById('downloadPosterBtn'); const shareWhatsAppBtn = document.getElementById('shareWhatsAppBtn'); + // Stage Theme Selector + const themeChips = document.querySelectorAll('#themeSelectorGroup .theme-chip'); + themeChips.forEach(chip => { + chip.addEventListener('click', () => { + themeChips.forEach(c => c.classList.remove('active')); + chip.classList.add('active'); + selectedStageTheme = chip.getAttribute('data-theme'); + }); + }); + let attachedImageBitmap = null; // Photo Input change @@ -171,9 +661,13 @@ function initPosterLab() { generatePosterBtn.addEventListener('click', async () => { const inputVal = productInput.value.trim(); const priceVal = productPrice.value.trim(); + const badgeText = customBadgeInput ? customBadgeInput.value.trim() : '🇰🇷 100% Original Korea'; + const aspect = aspectRatioSelect ? aspectRatioSelect.value : '1:1'; + const brand = brandSelect ? brandSelect.value : 'glamourstouch'; posterStatusText.classList.remove('hidden'); - posterStatusText.textContent = 'âŗ Resolving product image & rendering 3D gold stage...'; + posterStatusText.style.color = '#F59E0B'; + posterStatusText.textContent = 'âŗ Rendering 3D stage with GPU canvas blend...'; generatePosterBtn.disabled = true; try { @@ -181,27 +675,34 @@ function initPosterLab() { let title = "Authentic Korean K-Beauty Care"; if (!productImg) { - // Universal Product / Image Link Resolver const resolved = await resolveProductUrl(inputVal); if (resolved && resolved.imageUrl) { title = resolved.title || inputVal; productImg = await loadImage(resolved.imageUrl); } else { - // Fallback packshot image - const fallbackUrl = `https://image.pollinations.ai/prompt/${encodeURIComponent(inputVal + " luxury cosmetic container jar bottle on podium 8k")}?width=1024&height=1024&nologo=true`; + const fallbackUrl = `https://images.unsplash.com/photo-1556228720-195a672e8a03?w=800&h=800&fit=crop`; productImg = await loadImage(fallbackUrl); title = inputVal; } } if (productImg) { - // Render True 3D Poster on Canvas - await render3DCommercialPoster(posterCanvas, productImg, title, priceVal); + if (aspect === '9:16') { + posterCanvas.width = 1080; + posterCanvas.height = 1920; + canvasContainer.classList.add('aspect-reels'); + } else { + posterCanvas.width = 1080; + posterCanvas.height = 1080; + canvasContainer.classList.remove('aspect-reels'); + } + + await render3DCommercialPoster(posterCanvas, productImg, title, priceVal, badgeText, selectedStageTheme, aspect, brand); + posterResultCard.classList.remove('hidden'); posterStatusText.classList.add('hidden'); posterResultCard.scrollIntoView({ behavior: 'smooth' }); - // Save to History saveGenerationToHistory({ type: '3D Poster', title: title, @@ -209,7 +710,7 @@ function initPosterLab() { date: new Date().toLocaleTimeString() }); } else { - posterStatusText.textContent = '❌ Failed to load product image. Please check link.'; + posterStatusText.textContent = '❌ Failed to load product image.'; } } catch (err) { posterStatusText.textContent = `❌ Error: ${err.message}`; @@ -218,21 +719,21 @@ function initPosterLab() { generatePosterBtn.disabled = false; }); - // Download Button (Save to iPhone Camera Roll) + // Download downloadPosterBtn.addEventListener('click', () => { const link = document.createElement('a'); - link.download = `GT_Poster_${Date.now()}.jpg`; + link.download = `Opal_3D_Poster_${Date.now()}.jpg`; link.href = posterCanvas.toDataURL('image/jpeg', 0.95); link.click(); }); - // WhatsApp Order Button + // WhatsApp shareWhatsAppBtn.addEventListener('click', () => { - const text = encodeURIComponent(`✨ 100% Authentic Korean Skincare Order!\nProduct: ${productInput.value}\nPrice: ${productPrice.value}\nWebsite: https://glamourstouch.com`); + const text = encodeURIComponent(`✨ 100% Authentic Product Order!\nProduct: ${productInput.value}\nPrice: ${productPrice.value}\nWebsite: https://glamourstouch.com`); window.open(`https://wa.me/8801712426871?text=${text}`, '_blank'); }); - // 1-Click Auto Post to Facebook Page (via n8n Webhook) + // n8n Auto-Post Webhook const autoPostN8nBtn = document.getElementById('autoPostN8nBtn'); const n8nPostStatusMsg = document.getElementById('n8nPostStatusMsg'); @@ -240,22 +741,22 @@ function initPosterLab() { autoPostN8nBtn.addEventListener('click', async () => { const webhookUrl = localStorage.getItem('opal_n8n_webhook'); if (!webhookUrl) { - alert('âš ī¸ Please set your n8n Webhook URL in Settings first!'); - document.querySelector('.nav-item[data-tab="tabSettings"]').click(); + alert('âš ī¸ Please configure n8n Webhook URL in Settings first!'); + switchToTab('tabSettings'); return; } n8nPostStatusMsg.classList.remove('hidden'); n8nPostStatusMsg.style.color = '#38BDF8'; - n8nPostStatusMsg.textContent = 'âŗ Sending 3D poster & caption to n8n Webhook...'; + n8nPostStatusMsg.textContent = 'âŗ Sending 3D poster & copy to n8n Webhook...'; autoPostN8nBtn.disabled = true; try { const posterDataUrl = posterCanvas.toDataURL('image/jpeg', 0.92); const payload = { - title: productInput.value.trim() || 'Authentic Korean K-Beauty Skincare', + title: productInput.value.trim() || 'Authentic K-Beauty Skincare', price: productPrice.value.trim() || 'ā§ŗ ā§§,ā§Ļā§Ŧā§Ļ', - caption: `✨ ${productInput.value.trim()} ✨\n\n💰 āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ${productPrice.value.trim()}\nđŸ›Ąī¸ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϕ⧋āϰāĻŋ⧟āĻžāύ āĻ•āϏāĻŽā§‡āϟāĻŋāĻ•ā§āϏ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ!\n\nđŸ’Ŧ āϏāϰāĻžāϏāϰāĻŋ WhatsApp āĻ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ:\n👉 https://wa.me/8801712426871\n📞 āĻšāϟāϞāĻžāχāύ: 01712-426871\n🌐 āĻ“ā§Ÿā§‡āĻŦāϏāĻžāχāϟ: https://glamourstouch.com`, + caption: `✨ ${productInput.value.trim()} ✨\n\n💰 āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ${productPrice.value.trim()}\nđŸ›Ąī¸ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ!\n\nđŸ’Ŧ āϏāϰāĻžāϏāϰāĻŋ WhatsApp āĻ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ:\n👉 https://wa.me/8801712426871\n📞 āĻšāϟāϞāĻžāχāύ: 01712-426871\n🌐 āĻ“ā§Ÿā§‡āĻŦāϏāĻžāχāϟ: https://glamourstouch.com`, image_url: posterDataUrl, store: "Glamour's Touch", website: "https://glamourstouch.com", @@ -287,21 +788,19 @@ function initPosterLab() { } } -// Universal Link & Product Name Resolver +// Universal Link Resolver async function resolveProductUrl(input) { if (!input) return null; if (input.match(/\.(jpeg|jpg|gif|png|webp)($|\?)/i)) { - return { title: 'Authentic Korean Product', imageUrl: input }; + return { title: 'Authentic Product', imageUrl: input }; } const key = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZtY2x0cmpudXZ1b29hcmt2dWZuIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzUxMzY3MDQsImV4cCI6MjA5MDcxMjcwNH0.PkSgBAZx41X4sZurfyOdxCVa01hkKTkyBhVkGzx_4y4'; - // 1. Glamour's Touch Supabase UUID regex const uuidMatch = input.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/); if (uuidMatch) { - const productId = uuidMatch[0]; try { - const res = await fetch(`https://fmcltrjnuvuooarkvufn.supabase.co/rest/v1/products?id=eq.${productId}&select=*`, { + const res = await fetch(`https://fmcltrjnuvuooarkvufn.supabase.co/rest/v1/products?id=eq.${uuidMatch[0]}&select=*`, { headers: { 'apikey': key, 'Authorization': `Bearer ${key}` } }); const data = await res.json(); @@ -318,7 +817,6 @@ async function resolveProductUrl(input) { } } - // 2. Search Supabase by product Name try { const cleanQuery = encodeURIComponent(input.replace(/https?:\/\/[^\s]+/g, '').trim().slice(0, 30)); if (cleanQuery) { @@ -339,25 +837,7 @@ async function resolveProductUrl(input) { console.warn('GT Supabase search by name failed:', e); } - // 3. Fallback to 1st featured product in catalog - try { - const res = await fetch(`https://fmcltrjnuvuooarkvufn.supabase.co/rest/v1/products?in_stock=eq.true&image=not.is.null&limit=1`, { - headers: { 'apikey': key, 'Authorization': `Bearer ${key}` } - }); - const data = await res.json(); - if (data && data.length > 0) { - const p = data[0]; - return { - title: p.name || input, - price: p.price ? 'ā§ŗ ' + p.price : '', - imageUrl: p.image || '' - }; - } - } catch (e) { - console.warn('Fallback failed:', e); - } - - return { title: input, imageUrl: 'https://fmcltrjnuvuooarkvufn.supabase.co/storage/v1/object/public/products/product-images/koba-74d48daa-7695-41f9-8f10-9e5fb4f0e2d9.jpg' }; + return { title: input, imageUrl: 'https://images.unsplash.com/photo-1556228720-195a672e8a03?w=800&h=800&fit=crop' }; } function loadImage(src) { @@ -374,130 +854,140 @@ function loadImage(src) { const fallbackImg = new Image(); fallbackImg.crossOrigin = 'anonymous'; fallbackImg.onload = () => resolve(fallbackImg); - fallbackImg.onerror = () => reject(new Error('Could not load image across CORS')); + fallbackImg.onerror = () => reject(new Error('Could not load image')); fallbackImg.src = src; }; img.src = loadUrl; }); } -// --- 4. Masterpiece 3D Canvas Rendering Engine --- -async function render3DCommercialPoster(canvas, productImg, title, price) { +// --- 3D Canvas Multi-Theme Rendering Engine --- +async function render3DCommercialPoster(canvas, productImg, title, price, badgeText, theme = 'obsidian_gold', aspect = '1:1', brand = 'glamourstouch') { const ctx = canvas.getContext('2d'); - const w = 1080; - const h = 1080; + const w = canvas.width; + const h = canvas.height; - // 1. Midnight Obsidian Background - const bgGrad = ctx.createRadialGradient(w / 2, h * 0.44, 50, w / 2, h * 0.44, w * 0.72); - bgGrad.addColorStop(0, '#18212D'); - bgGrad.addColorStop(0.6, '#0C1117'); - bgGrad.addColorStop(1, '#05080C'); + // Theme palettes + const THEMES = { + obsidian_gold: { + bgCenter: '#18212D', bgMid: '#0C1117', bgOuter: '#05080C', + spotlightColor: '#FFFFFF', goldRim: '#E5B83A', ringColor: '#66E5B83A', + pedestalTop: '#FFFFFF', pedestalMid: '#EBF2F8', pedestalDark: '#1B2533', + headerTitle: '✨ GLAMOUR\'S TOUCH ✨', headerSub: '대한ë¯ŧęĩ­ 프ëĻŦë¯¸ė—„ ėŠ¤í‚¨āϕ⧇āϝāĻŧāĻžāϰ â€ĸ 100% AUTHENTIC KOREAN COSMETICS' + }, + rose_quartz: { + bgCenter: '#2D1824', bgMid: '#170C13', bgOuter: '#0C0509', + spotlightColor: '#FFF0F5', goldRim: '#F472B6', ringColor: '#F472B666', + pedestalTop: '#FFF5F8', pedestalMid: '#FCE7F3', pedestalDark: '#371829', + headerTitle: '🌸 SNEHALATA AURA 🌸', headerSub: 'PREMIUM LUXURY LIFESTYLE â€ĸ 100% AUTHENTIC BEAUTY' + }, + cyber_neon: { + bgCenter: '#0F172A', bgMid: '#060E1A', bgOuter: '#02060D', + spotlightColor: '#E0F2FE', goldRim: '#06B6D4', ringColor: '#06B6D466', + pedestalTop: '#F0FDF4', pedestalMid: '#CFFAFE', pedestalDark: '#082F49', + headerTitle: '💎 AURA ENTERPRISE 💎', headerSub: 'NEXT-GEN AGENTIC COMMERCE â€ĸ AI EMPOWERED' + }, + botanical_eco: { + bgCenter: '#14281E', bgMid: '#0B1711', bgOuter: '#040B07', + spotlightColor: '#F0FDF4', goldRim: '#10B981', ringColor: '#10B98166', + pedestalTop: '#F7FEE7', pedestalMid: '#DCFCE7', pedestalDark: '#064E3B', + headerTitle: 'đŸŒŋ PURE BOTANICAL CARE đŸŒŋ', headerSub: 'ORGANIC DERMATOLOGY â€ĸ CLINICALLY PROVEN' + } + }; + + const currentTheme = THEMES[theme] || THEMES.obsidian_gold; + + // 1. Background Radial Gradient + const stageCy = aspect === '9:16' ? h * 0.46 : h * 0.44; + const bgGrad = ctx.createRadialGradient(w / 2, stageCy, 50, w / 2, stageCy, w * 0.75); + bgGrad.addColorStop(0, currentTheme.bgCenter); + bgGrad.addColorStop(0.6, currentTheme.bgMid); + bgGrad.addColorStop(1, currentTheme.bgOuter); ctx.fillStyle = bgGrad; ctx.fillRect(0, 0, w, h); - // 2. White-to-Midnight Luxury Radial Spotlight (Smooth Studio Blend) + // 2. Spotlight const stageCx = w / 2; - const stageCy = h * 0.44; const stageRadius = w * 0.38; const spotGrad = ctx.createRadialGradient(stageCx, stageCy, 0, stageCx, stageCy, stageRadius); spotGrad.addColorStop(0, '#FFFFFF'); - spotGrad.addColorStop(0.46, '#FFFFFF'); - spotGrad.addColorStop(0.64, '#F0F5FA'); - spotGrad.addColorStop(0.82, '#8E9FAC'); - spotGrad.addColorStop(0.94, '#283545'); - spotGrad.addColorStop(1, '#0C1117'); + spotGrad.addColorStop(0.48, '#FFFFFF'); + spotGrad.addColorStop(0.68, currentTheme.spotlightColor); + spotGrad.addColorStop(0.85, '#64748B'); + spotGrad.addColorStop(1, 'transparent'); ctx.fillStyle = spotGrad; ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius, 0, Math.PI * 2); ctx.fill(); - // Luxury Gold Dashed Rings - ctx.strokeStyle = '#66E5B83A'; + // Glow Rings + ctx.strokeStyle = currentTheme.ringColor; ctx.lineWidth = 2.5; ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius * 0.96, 0, Math.PI * 2); ctx.stroke(); - ctx.strokeStyle = '#99E5B83A'; - ctx.lineWidth = 1.8; ctx.setLineDash([12, 12]); ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius * 0.91, 0, Math.PI * 2); ctx.stroke(); ctx.setLineDash([]); - // 3. True 3D Dual-Tier Cylindrical Podium - // --- TIER 1: Lower Base --- - const baseTierY = 745; + // 3. 3D Dual-Tier Podium + const baseTierY = aspect === '9:16' ? 1220 : 745; const baseTierRx = w * 0.38; const baseTierRy = 34; const baseTierHeight = 26; - // Tier 1 Ground Shadow + // Base Shadow const baseShadow = ctx.createRadialGradient(stageCx, baseTierY + baseTierHeight + 16, 20, stageCx, baseTierY + baseTierHeight + 16, baseTierRx * 1.15); baseShadow.addColorStop(0, 'rgba(0,0,0,0.7)'); baseShadow.addColorStop(1, 'transparent'); ctx.fillStyle = baseShadow; drawOval(ctx, stageCx, baseTierY + baseTierHeight + baseTierRy * 0.6, baseTierRx * 1.15, baseTierRy * 1.6); - // Tier 1 Cylinder Body + // Base Cylinder Body const baseCylGrad = ctx.createLinearGradient(stageCx - baseTierRx, 0, stageCx + baseTierRx, 0); baseCylGrad.addColorStop(0, '#090D12'); - baseCylGrad.addColorStop(0.2, '#1C2633'); - baseCylGrad.addColorStop(0.5, '#6C829E'); - baseCylGrad.addColorStop(0.8, '#1C2633'); + baseCylGrad.addColorStop(0.5, '#475569'); baseCylGrad.addColorStop(1, '#090D12'); ctx.fillStyle = baseCylGrad; ctx.fillRect(stageCx - baseTierRx, baseTierY, baseTierRx * 2, baseTierHeight); drawOval(ctx, stageCx, baseTierY + baseTierHeight, baseTierRx, baseTierRy); - - // Tier 1 Top Cap - const baseTopGrad = ctx.createLinearGradient(stageCx - baseTierRx, baseTierY - baseTierRy, stageCx + baseTierRx, baseTierY + baseTierRy); - baseTopGrad.addColorStop(0, '#222D3A'); - baseTopGrad.addColorStop(1, '#0B1017'); - ctx.fillStyle = baseTopGrad; drawOval(ctx, stageCx, baseTierY, baseTierRx, baseTierRy); - // --- TIER 2: Upper Product Pedestal --- - const topTierY = 708; + // Top Tier + const topTierY = aspect === '9:16' ? 1180 : 708; const topTierRx = w * 0.31; const topTierRy = 28; const topTierHeight = 34; - // Tier 2 Cylinder Body const topCylGrad = ctx.createLinearGradient(stageCx - topTierRx, 0, stageCx + topTierRx, 0); topCylGrad.addColorStop(0, '#070A0E'); - topCylGrad.addColorStop(0.25, '#18212C'); - topCylGrad.addColorStop(0.5, '#F5E6AB'); - topCylGrad.addColorStop(0.75, '#18212C'); + topCylGrad.addColorStop(0.5, currentTheme.goldRim); topCylGrad.addColorStop(1, '#070A0E'); ctx.fillStyle = topCylGrad; ctx.fillRect(stageCx - topTierRx, topTierY, topTierRx * 2, topTierHeight); drawOval(ctx, stageCx, topTierY + topTierHeight, topTierRx, topTierRy); - // Tier 2 Top Surface (Glossy White/Platinum Cap) + // Top Surface Cap const topSurfaceGrad = ctx.createRadialGradient(stageCx, topTierY, 0, stageCx, topTierY, topTierRx); - topSurfaceGrad.addColorStop(0, '#FFFFFF'); - topSurfaceGrad.addColorStop(0.45, '#EBF2F8'); - topSurfaceGrad.addColorStop(0.8, '#899EAF'); - topSurfaceGrad.addColorStop(1, '#1B2533'); + topSurfaceGrad.addColorStop(0, currentTheme.pedestalTop); + topSurfaceGrad.addColorStop(0.5, currentTheme.pedestalMid); + topSurfaceGrad.addColorStop(1, currentTheme.pedestalDark); ctx.fillStyle = topSurfaceGrad; drawOval(ctx, stageCx, topTierY, topTierRx, topTierRy); - // Tier 2 Top Gold Beveled Rim - const goldRimGrad = ctx.createLinearGradient(stageCx - topTierRx, topTierY, stageCx + topTierRx, topTierY); - goldRimGrad.addColorStop(0, '#B38728'); - goldRimGrad.addColorStop(0.5, '#FFFFFF'); - goldRimGrad.addColorStop(1, '#AA771C'); - ctx.strokeStyle = goldRimGrad; + // Gold Beveled Rim + ctx.strokeStyle = currentTheme.goldRim; ctx.lineWidth = 3.5; strokeOval(ctx, stageCx, topTierY, topTierRx, topTierRy); - // 4. Hero Product Scaling & Placement - const targetH = 500; - const targetW = 520; + // 4. Product Scaling & Placement + const targetH = aspect === '9:16' ? 560 : 500; + const targetW = aspect === '9:16' ? 580 : 520; const srcW = productImg.width || 500; const srcH = productImg.height || 500; const scale = Math.min(targetW / srcW, targetH / srcH); @@ -506,7 +996,7 @@ async function render3DCommercialPoster(canvas, productImg, title, price) { const destLeft = (w - destW) / 2; const destTop = topTierY - destH + 18; - // 4.1 Glossy Mirror Product Reflection (Multiply blended) + // Floor Reflection (Multiply blend) ctx.save(); ctx.globalCompositeOperation = 'multiply'; ctx.globalAlpha = 0.25; @@ -522,48 +1012,50 @@ async function render3DCommercialPoster(canvas, productImg, title, price) { ctx.fillStyle = contactShadow; drawOval(ctx, stageCx, topTierY + 2, destW * 0.38, 12); - // Draw Hero Product with Multiply Blend Mode (removes white background completely) + // Product Image (Multiply blended to wipe white background) ctx.save(); ctx.globalCompositeOperation = 'multiply'; ctx.drawImage(productImg, destLeft, destTop, destW, destH); ctx.restore(); // 5. Value Trust Badges - drawPillBadge(ctx, 40, 240, '🇰🇷 100% Original Korea', true); - drawPillBadge(ctx, 40, 315, 'đŸŒŋ Skin Friendly Formula', true); - drawPillBadge(ctx, w - 40, 240, '⚡ Fast Delivery BD', false); - drawPillBadge(ctx, w - 40, 315, 'đŸ›Ąī¸ Authentic Guarantee', false); + const badgeY1 = aspect === '9:16' ? 340 : 240; + const badgeY2 = badgeY1 + 75; + drawPillBadge(ctx, 40, badgeY1, badgeText, true, currentTheme.goldRim); + drawPillBadge(ctx, 40, badgeY2, 'đŸŒŋ Skin Friendly Formula', true, currentTheme.goldRim); + drawPillBadge(ctx, w - 40, badgeY1, '⚡ Fast Delivery BD', false, currentTheme.goldRim); + drawPillBadge(ctx, w - 40, badgeY2, 'đŸ›Ąī¸ Authentic Guarantee', false, currentTheme.goldRim); - // 6. Top Header Ribbon + // 6. Header Ribbon ctx.fillStyle = '#F2090D12'; ctx.fillRect(0, 0, w, 92); - ctx.strokeStyle = '#E5B83A'; + ctx.strokeStyle = currentTheme.goldRim; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(0, 92); ctx.lineTo(w, 92); ctx.stroke(); - ctx.fillStyle = '#E5B83A'; - ctx.font = 'bold 34px Plus Jakarta Sans, sans-serif'; + ctx.fillStyle = currentTheme.goldRim; + ctx.font = 'bold 32px Plus Jakarta Sans, sans-serif'; ctx.textAlign = 'center'; - ctx.fillText('✨ GLAMOUR\'S TOUCH ✨', w / 2, 52); + ctx.fillText(currentTheme.headerTitle, w / 2, 52); ctx.fillStyle = '#FFF4D0'; - ctx.font = '17px Plus Jakarta Sans, sans-serif'; - ctx.fillText('대한ë¯ŧęĩ­ 프ëĻŦë¯¸ė—„ ėŠ¤í‚¨ėŧ€ė–´ â€ĸ 100% AUTHENTIC KOREAN COSMETICS', w / 2, 80); + ctx.font = '16px Plus Jakarta Sans, sans-serif'; + ctx.fillText(currentTheme.headerSub, w / 2, 80); // 7. Product Title Card const cleanTitle = title.length > 60 ? title.substring(0, 58) + '...' : title; - const titleCardTop = h - 235; - const titleCardBottom = h - 128; + const titleCardTop = h - (aspect === '9:16' ? 320 : 235); + const titleCardBottom = h - (aspect === '9:16' ? 150 : 128); ctx.fillStyle = '#EA0B0E14'; roundRect(ctx, 28, titleCardTop, w - 56, titleCardBottom - titleCardTop, 18); ctx.fill(); - ctx.strokeStyle = '#55E5B83A'; + ctx.strokeStyle = currentTheme.goldRim + '88'; ctx.lineWidth = 2; roundRect(ctx, 28, titleCardTop, w - 56, titleCardBottom - titleCardTop, 18); ctx.stroke(); @@ -573,32 +1065,33 @@ async function render3DCommercialPoster(canvas, productImg, title, price) { ctx.textAlign = 'center'; ctx.fillText(cleanTitle, w / 2, titleCardTop + 42); - ctx.fillStyle = '#E5B83A'; - ctx.font = 'bold 20px Hind Siliguri, sans-serif'; - ctx.fillText('āĻ—ā§āϞāĻžāϏ āĻ¸ā§āĻ•āĻŋāύ āĻ“ āĻĻāĻžāĻ—āĻšā§€āύ āωāĻœā§āĻœā§āĻŦāϞāϤāĻžāϰ āϕ⧋āϰāĻŋ⧟āĻžāύ āϏāĻŋāĻ•ā§āϰ⧇āϟ â€ĸ āϏāϰāĻžāϏāϰāĻŋ āϕ⧋āϰāĻŋ⧟āĻž āĻĨ⧇āϕ⧇ āφāĻŽāĻĻāĻžāύāĻŋāĻ•ā§ƒāϤ', w / 2, titleCardTop + 78); + ctx.fillStyle = currentTheme.goldRim; + ctx.font = 'bold 21px Hind Siliguri, sans-serif'; + ctx.fillText(`${price} â€ĸ ā§§ā§Ļā§Ļ% āφāϏāϞ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ â€ĸ āĻĻā§āϰ⧁āϤ āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ`, w / 2, titleCardTop + 80); - // 8. Bottom WhatsApp Order Ribbon (Green Banner) - const footerTop = h - 118; + // 8. Bottom WhatsApp Banner + const footerHeight = aspect === '9:16' ? 140 : 118; + const footerTop = h - footerHeight; const footerGrad = ctx.createLinearGradient(0, footerTop, w, h); footerGrad.addColorStop(0, '#25D366'); footerGrad.addColorStop(1, '#1EB855'); ctx.fillStyle = footerGrad; - ctx.fillRect(0, footerTop, w, 118); + ctx.fillRect(0, footerTop, w, footerHeight); ctx.fillStyle = '#FFFFFF'; ctx.font = 'bold 32px Plus Jakarta Sans, sans-serif'; ctx.textAlign = 'left'; - ctx.fillText('đŸ’Ŧ WhatsApp: 01712-426871', 35, footerTop + 48); + ctx.fillText('đŸ’Ŧ WhatsApp Order: 01712-426871', 35, footerTop + 48); ctx.fillStyle = '#053314'; - ctx.font = 'bold 21px Plus Jakarta Sans, sans-serif'; - ctx.fillText('🌐 Website: glamourstouch.com â€ĸ 📞 Call: 01712-426871', 35, footerTop + 90); + ctx.font = 'bold 20px Plus Jakarta Sans, sans-serif'; + ctx.fillText('🌐 Website: glamourstouch.com â€ĸ 📞 Hotline: 01712-426871', 35, footerTop + 90); - // 8.1 Render Scannable QR Code on Bottom Right + // QR Code await drawWhatsAppQrOnCanvas(ctx, w - 130, footerTop + 11, 96); - // 9. Outer Gold Frame Edge - ctx.strokeStyle = '#88E5B83A'; + // Outer Border + ctx.strokeStyle = currentTheme.goldRim + '99'; ctx.lineWidth = 6; ctx.strokeRect(3, 3, w - 6, h - 6); } @@ -629,7 +1122,7 @@ function roundRect(ctx, x, y, width, height, radius) { ctx.closePath(); } -function drawPillBadge(ctx, x, y, text, isLeft) { +function drawPillBadge(ctx, x, y, text, isLeft, goldColor = '#E5B83A') { ctx.font = 'bold 18px Plus Jakarta Sans, Hind Siliguri, sans-serif'; const textWidth = ctx.measureText(text).width; const pillW = textWidth + 28; @@ -641,7 +1134,7 @@ function drawPillBadge(ctx, x, y, text, isLeft) { roundRect(ctx, pillX, pillY, pillW, pillH, 18); ctx.fill(); - ctx.strokeStyle = '#55E5B83A'; + ctx.strokeStyle = goldColor + '66'; ctx.lineWidth = 1.5; roundRect(ctx, pillX, pillY, pillW, pillH, 18); ctx.stroke(); @@ -652,31 +1145,31 @@ function drawPillBadge(ctx, x, y, text, isLeft) { } async function drawWhatsAppQrOnCanvas(ctx, x, y, size) { - // White background container ctx.fillStyle = '#FFFFFF'; roundRect(ctx, x - 4, y - 4, size + 8, size + 8, 10); ctx.fill(); - // Create temporary QR element const qrContainer = document.getElementById('qrcodeHidden'); - qrContainer.innerHTML = ''; - new QRCode(qrContainer, { - text: 'https://wa.me/8801712426871', - width: size, - height: size, - colorDark: '#0B2E13', - colorLight: '#FFFFFF', - correctLevel: QRCode.CorrectLevel.M - }); + if (qrContainer) { + qrContainer.innerHTML = ''; + new QRCode(qrContainer, { + text: 'https://wa.me/8801712426871', + width: size, + height: size, + colorDark: '#0B2E13', + colorLight: '#FFFFFF', + correctLevel: QRCode.CorrectLevel.M + }); - await new Promise(r => setTimeout(r, 80)); - const qrImg = qrContainer.querySelector('img') || qrContainer.querySelector('canvas'); - if (qrImg) { - ctx.drawImage(qrImg, x, y, size, size); + await new Promise(r => setTimeout(r, 80)); + const qrImg = qrContainer.querySelector('img') || qrContainer.querySelector('canvas'); + if (qrImg) { + ctx.drawImage(qrImg, x, y, size, size); + } } } -// --- 5. Customer Care & Inbox AI --- +// --- Customer Care & Inbox AI Dedicated Studio --- function initInboxAI() { const customerMsgInput = document.getElementById('inboxCustomerMsg'); const storeContextInput = document.getElementById('inboxStoreContext'); @@ -687,11 +1180,13 @@ function initInboxAI() { const reply2 = document.getElementById('replyText2'); const reply3 = document.getElementById('replyText3'); + if (!generateBtn) return; + generateBtn.addEventListener('click', async () => { const query = customerMsgInput.value.trim(); const storeInfo = storeContextInput.value.trim(); const apiKey = localStorage.getItem('opal_gemini_api_key') || ''; - const model = localStorage.getItem('opal_selected_model') || 'gemini-3.6-flash'; + const model = localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; if (!query) { alert('Please enter a customer message'); @@ -699,12 +1194,12 @@ function initInboxAI() { } statusMsg.classList.remove('hidden'); - statusMsg.textContent = 'âŗ Generating 3 sweet & polite sales replies with Gemma AI...'; + statusMsg.textContent = 'âŗ Generating 3 sweet & polite sales replies with Gemini AI...'; generateBtn.disabled = true; try { if (apiKey) { - const prompt = `A customer sent this message in Glamour's Touch inbox: + const prompt = `A customer sent this message in e-commerce inbox: '${query}' Store Info: ${storeInfo} @@ -720,11 +1215,10 @@ Format exactly with: const result = await callGeminiApi(apiKey, model, prompt); const parts = result.split(/---REPLY[123]---/); - reply1.textContent = (parts[1] || 'āφāϏāϏāĻžāϞāĻžāĻŽā§ āφāϞāĻžāχāϕ⧁āĻŽ āĻĒā§āϰāĻŋ⧟ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ! āφāĻŽāĻžāĻĻ⧇āϰ āĻ—ā§āϞāĻžāϏ āĻ¸ā§āĻ•āĻŋāύ āϏāĻŋāϰāĻžāĻŽā§‡āϰ āĻĻāĻžāĻŽ āĻŽāĻžāĻ¤ā§āϰ ā§ŗā§§ā§Ŧā§Ļā§ĻāĨ¤ āĻāϟāĻŋ ā§§ā§Ļā§Ļ% āφāϏāϞ āϕ⧋āϰāĻŋ⧟āĻžāύ āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟāĨ¤').trim(); + reply1.textContent = (parts[1] || 'āφāϏāϏāĻžāϞāĻžāĻŽā§ āφāϞāĻžāχāϕ⧁āĻŽ āĻĒā§āϰāĻŋ⧟ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ! āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ āĻŽāĻžāĻ¤ā§āϰ ā§ŗā§§ā§Ļā§Ŧā§ĻāĨ¤ āĻāϟāĻŋ ā§§ā§Ļā§Ļ% āφāϏāϞ āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟāĨ¤').trim(); reply2.textContent = (parts[2] || 'āĻ…āĻ°ā§āĻĄāĻžāϰāϟāĻŋ āĻ•āύāĻĢāĻžāĻ°ā§āĻŽ āĻ•āϰāϤ⧇ āφāĻĒāύāĻžāϰ āύāĻžāĻŽ, āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ āĻŋāĻ•āĻžāύāĻž āĻāĻŦāĻ‚ āĻŽā§‹āĻŦāĻžāχāϞ āύāĻŽā§āĻŦāϰāϟāĻŋ āϞāĻŋāϖ⧇ āĻĒāĻžāĻ āĻžāύāĨ¤ āφāĻŽāϰāĻž āĻĻā§āϰ⧁āϤ āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻ⧇āĻŦā§‹!').trim(); reply3.textContent = (parts[3] || 'āϏāϰāĻžāϏāϰāĻŋ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇ āĻĻā§āϰ⧁āϤ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ: https://wa.me/8801712426871\nāĻšāϟāϞāĻžāχāύ: 01712-426871').trim(); } else { - // High quality offline fallback template reply1.textContent = `āφāϏāϏāĻžāϞāĻžāĻŽā§ āφāϞāĻžāχāϕ⧁āĻŽ āĻĒā§āϰāĻŋ⧟ āφāĻĒ⧁/āĻ­āĻžāĻ‡ā§ŸāĻž! đŸĨ°\nāφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϕ⧋āϰāĻŋ⧟āĻžāύ āĻ¸ā§āĻ•āĻŋāύāĻ•ā§‡ā§ŸāĻžāϰ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤\n\n💰 āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ā§ŗ ā§§,ā§Ļā§Ŧā§Ļ (āϰ⧇āϗ⧁āϞāĻžāϰ ā§ŗ ā§§,ā§Ēā§­ā§Ļ)\n🚚 āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ: āĻĸāĻžāĻ•āĻžā§Ÿ ā§ŗā§­ā§Ļ, āĻĸāĻžāĻ•āĻžāϰ āĻŦāĻžāχāϰ⧇ ā§ŗā§§ā§Šā§Ļ\n\nāĻāϟāĻŋ āύāĻŋ⧟āĻŽāĻŋāϤ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇ āĻ¤ā§āĻŦāĻ• āĻšāĻŦ⧇ āĻ•āĻžāĻšā§‡āϰ āĻŽāϤ⧋ āϚāĻ•āϚāϕ⧇ āĻ“ āĻĻāĻžāĻ—āĻšā§€āύ! 🌸`; reply2.textContent = `āĻ…āĻ°ā§āĻĄāĻžāϰāϟāĻŋ āĻ•āύāĻĢāĻžāĻ°ā§āĻŽ āĻ•āϰāϤ⧇ āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āφāĻĒāύāĻžāϰ:\nā§§. āύāĻžāĻŽ\n⧍. āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ āĻŋāĻ•āĻžāύāĻž (āĻœā§‡āϞāĻž/āĻĨāĻžāύāĻž āϏāĻš)\nā§Š. āĻŽā§‹āĻŦāĻžāχāϞ āύāĻŽā§āĻŦāϰ\n\nāϞāĻŋāϖ⧇ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻāĻŋāύāĨ¤ āφāĻŽāϰāĻž āĻĻā§āϰ⧁āϤ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻ⧇āĻŦā§‹! āϧāĻ¨ā§āϝāĻŦāĻžāĻĻāĨ¤ đŸ›ī¸`; reply3.textContent = `āϏāϰāĻžāϏāϰāĻŋ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ:\nđŸ’Ŧ WhatsApp: https://wa.me/8801712426871\n📞 āĻšāϟāϞāĻžāχāύ: 01712-426871\n🌐 āĻ“ā§Ÿā§‡āĻŦāϏāĻžāχāϟ: https://glamourstouch.com`; @@ -741,38 +1235,44 @@ Format exactly with: }); } -// --- 6. History Management --- +// --- History Management --- function initHistory() { const historyContainer = document.getElementById('historyListContainer'); const clearBtn = document.getElementById('clearHistoryBtn'); function renderHistory() { + if (!historyContainer) return; const list = JSON.parse(localStorage.getItem('opal_history') || '[]'); if (list.length === 0) { historyContainer.innerHTML = `
📭 -

No generations yet. Create your first 3D poster or copy!

+

No generations yet. Create your first 3D poster or mini-app generation!

`; return; } historyContainer.innerHTML = list.map(item => `
-
${item.type === '3D Poster' ? '🎨' : 'đŸ’Ŧ'}
-
-

${item.title}

-

${item.price || item.type}

+
+
${item.type === '3D Poster' ? '🎨' : '⚡'}
+ ${item.type} +
+

${item.title}

+

${item.price || item.type}

+
`).join(''); } - clearBtn.addEventListener('click', () => { - localStorage.removeItem('opal_history'); - renderHistory(); - }); + if (clearBtn) { + clearBtn.addEventListener('click', () => { + localStorage.removeItem('opal_history'); + renderHistory(); + }); + } renderHistory(); } diff --git a/index.html b/index.html index 99a90cc..c91fc35 100644 --- a/index.html +++ b/index.html @@ -3,14 +3,14 @@ - Google Opal AI - iOS Studio & 3D Poster Lab + Google Opal AI - iOS Studio & 3D Mini-App Engine - + @@ -18,20 +18,23 @@ - +
-
+
💎
-

Opal AI Studio

-

Google DeepMind â€ĸ iOS Edition

+

Opal AI Studio PRO

+

Google DeepMind â€ĸ Mini-App Engine

+
@@ -39,33 +42,79 @@
- -
-
+ +
+
🎨

3D Commercial Poster Lab

-

āφāϏāϞ āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻ›āĻŦāĻŋ, ā§ŠāĻĄāĻŋ āĻŽāĻžāĻ°ā§āĻŦ⧇āϞ āĻĒā§‹āĻĄāĻŋ⧟āĻžāĻŽ āĻ“ WhatsApp QR āϏāĻš āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāύ āĻĒā§‹āĻ¸ā§āϟāĻžāϰ āĻŦāĻžāύāĻžāύ

+

āφāϏāϞ āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻ›āĻŦāĻŋ, ā§ŠāĻĄāĻŋ āĻŽāĻžāĻ°ā§āĻŦ⧇āϞ āĻ¸ā§āĻŸā§‡āϜ āĻ“ WhatsApp QR āϏāĻš āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāύ āĻĒā§‹āĻ¸ā§āϟāĻžāϰ āĻŦāĻžāύāĻžāύ

+
+
+ + +
+ +
+
+ 👑 + Obsidian & Gold +
+
+ 🌸 + Rose Quartz Glass +
+
+ 💎 + Cyberpunk Neon +
+
+ đŸŒŋ + Botanical Eco +
+
+
+ + +
+ +
+ +
- +
-
- - +
+
+ + +
+
+ + +
- +
-
- -
+ +
-

✨ Curated Opal Mini-Apps

- 6 Apps +
+

✨ Opal Mini-Apps Hub

+

+ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āĻĄā§āϝāĻžāĻļāĻŦā§‹āĻ°ā§āĻĄā§‡ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āϜāĻ¨ā§āϝ āĻ•āĻžāĻ¸ā§āϟāĻŽ āĻāφāχ āĻŽāĻŋāύāĻŋ-āĻ…ā§āϝāĻžāĻĒ āϤ⧈āϰāĻŋ āĻ“ āĻāĻŽā§āĻŦ⧇āĻĄ āĻ•āϰ⧁āύ +

+
+
-
- -
-
✨
-
-
-

Glamour's Touch 4K K-Beauty Studio

- GEM -
-

glamourstouch.com āĻāϰ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϕ⧋āϰāĻŋ⧟āĻžāύ āĻ¸ā§āĻ•āĻŋāύāϕ⧇āϝāĻŧāĻžāϰ⧇āϰ āĻ•āĻŽāĻžāĻ°ā§āĻļāĻŋ⧟āĻžāϞ āĻ›āĻŦāĻŋ āĻ“ āĻĒā§‹āĻ¸ā§āϟ āĻŦāĻžāύāĻžā§ŸāĨ¤

- 7 Steps â€ĸ Business -
-
+ +
+ + + + + + +
- -
-
đŸ’Ŧ
-
-
-

Customer Care & Inbox Auto-Reply

- AI -
-

āĻĢ⧇āϏāĻŦ⧁āĻ• āĻŽā§‡āϏ⧇āĻžā§āϜāĻžāϰ āĻ“ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĒā§āϰāĻļā§āύ⧇āϰ ā§ŠāϟāĻŋ āχāύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŦāĻŋāύāĻŽā§āϰ āϏ⧇āϞāϏ āϰāĻŋāĻĒā§āϞāĻžāχ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤

- 3 Steps â€ĸ Sales -
-
- - -
-
đŸ›ī¸
-
-

E-Commerce Product Launch Kit

-

āϝ⧇āϕ⧋āύ⧋ āĻĒāĻŖā§āϝ⧇āϰ 4K āĻ•āĻŽāĻžāĻ°ā§āĻļāĻŋ⧟āĻžāϞ āĻ›āĻŦāĻŋ āĻ“ āĻĢ⧇āϏāĻŦ⧁āĻ• āϞāĻžā§āϚ āĻ•āĻĒāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤

- 5 Steps â€ĸ Business -
-
- - -
-
đŸ”Ĩ
-
-

Viral Social Post & Reels Script

-

āĻĢ⧇āϏāĻŦ⧁āĻ•, āϟāĻŋāĻ•āϟāĻ• āĻ“ āχāύāĻ¸ā§āϟāĻžāĻ—ā§āϰāĻžāĻŽā§‡āϰ āĻ­āĻžāχāϰāĻžāϞ āĻšā§āĻ• āĻ“ āĻ­āĻŋāĻĄāĻŋāĻ“ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤

- 4 Steps â€ĸ Marketing -
-
+ +
+
- + +
+
+
+ đŸ› ī¸ +
+

Visual Mini-App Builder

+

āφāĻĒāύāĻžāϰ āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ āĻĄā§āϝāĻžāĻļāĻŦā§‹āĻ°ā§āĻĄā§‡āϰ āϜāĻ¨ā§āϝ āĻ•ā§Ÿā§‡āĻ• āĻ•ā§āϞāĻŋāϕ⧇ āĻ•āĻžāĻ¸ā§āϟāĻŽ āĻāφāχ āĻŽāĻŋāύāĻŋ-āĻ…ā§āϝāĻžāĻĒ āϤ⧈āϰāĻŋ āĻ•āϰ⧁āύ

+
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ +
+ + +
+
+ +
+ + + 💡 āĻŸā§‡āĻŽāĻĒā§āϞ⧇āĻŸā§‡āϰ āĻŽāĻ§ā§āϝ⧇ {{field1}} āĻāĻŦāĻ‚ {{field2}} āĻ¸ā§āĻŦ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇ āχāωāϜāĻžāϰ⧇āϰ āχāύāĻĒ⧁āϟ āĻĻāĻŋā§Ÿā§‡ āĻĒā§āϰāϤāĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻŋāϤ āĻšāĻŦ⧇āĨ¤ +
+ +
+ + +
+ +
+
+ +
-
+
đŸ’Ŧ
-

Glamour's Touch Customer Care & Inbox AI

-

āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻŽā§‡āϏ⧇āϜ āĻĻāĻŋāϞ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ ā§ŠāϟāĻŋ āĻĒāĻžāϰāĻĢ⧇āĻ•ā§āϟ āĻ“ āĻŦāĻŋāύāĻŽā§āϰ āωāĻ¤ā§āϤāϰ āϤ⧈āϰāĻŋ āĻ•āϰ⧇

+

Omnichannel Customer Care & Sales Closer AI

+

āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻŽā§‡āϏ⧇āϜ āĻĻāĻŋāϞ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ ā§ŠāϟāĻŋ āĻŽāĻŋāĻˇā§āϟāĻŋ āĻ“ āĻšāĻžāχ-āĻ•āύāĻ­āĻžāĻ°ā§āϟāĻŋāĻ‚ āωāĻ¤ā§āϤāϰ āϤ⧈āϰāĻŋ āĻ•āϰ⧇

- +
@@ -182,16 +284,16 @@
-
- +
-

📜 Saved History

+

📜 Saved Generation History

📭 -

No generations yet. Create your first 3D poster or copy!

+

No generations yet. Create your first 3D poster or mini-app generation!

- +
-
+
âš™ī¸
-

Settings & Free AI Engine

-

āϗ⧁āĻ—āϞ āĻœā§‡āĻŽāĻŋāύāĻŋ āĻ“ āĻ—ā§āϝāĻžāĻŽāĻž āĻ“āĻĒ⧇āύ āĻŽāĻĄā§‡āϞ āϏ⧇āϟāφāĻĒ

+

Settings & Google AI Configuration

+

āϗ⧁āĻ—āϞ āĻœā§‡āĻŽāĻŋāύāĻŋ ⧍.ā§Ļ āĻ“ āĻ—ā§āϝāĻžāĻŽāĻž āĻ“āĻĒ⧇āύ āĻŽāĻĄā§‡āϞ āϏ⧇āϟāφāĻĒ

- + - API Key is saved securely in your iPhone's local storage. + API Key is saved securely in your browser/device local storage.
@@ -268,9 +369,11 @@
-
+

💎 About Google Opal AI (iOS Edition)

-

This web studio is engineered specifically for **iPhone (iOS Safari / PWA)** with 0ms latency, native 2D canvas GPU rendering, and official Google Gemma & Gemini AI integration.

+

+ This web studio is engineered specifically for iPhone (iOS Safari / PWA) and client dashboards with 0ms latency, native 2D canvas GPU rendering, and official Google Gemini 2.0 AI integration. +

📲 iPhone āϟāĻŋāĻĒāϏ: Safari-āĻāϰ āύāĻŋāĻšā§‡ āĻĨāĻžāĻ•āĻž Share (📤) āĻŦāĻžāϟāύ⧇ āĻŸā§āϝāĻžāĻĒ āĻ•āϰ⧇ "Add to Home Screen" āϚāĻžāĻĒ⧁āύāĨ¤ āϤāĻžāĻšāϞ⧇ āĻāϟāĻŋ āφāĻĒāύāĻžāϰ āφāχāĻĢā§‹āύ⧇ āĻāĻ•āĻĻāĻŽ āφāϏāϞ āĻ…ā§āϝāĻžāĻĒ⧇āϰ āĻŽāϤ⧋ āĻĢ⧁āϞ-āĻ¸ā§āĻ•ā§āϰāĻŋāύ⧇ āϚāϞāĻŦ⧇!
@@ -281,32 +384,89 @@ + + + + + + - +