(function(){ 'use strict'; /* ══════════════════════════════════════ CONFIG — SỬA Ở ĐÂY ══════════════════════════════════════ */ var SITE_URL = 'https://adscoffee.vn'; var PAYMENT_URL = 'https://adscoffee.vn/san-pham/prompt-studio-premium-ads-builder-ai-content-calendar-ai/'; var API_ENDPOINT = 'https://adscoffee.vn/wp-json/adscoffee/v1/claude-proxy'; // Free limits per day (localStorage) var FREE_LIMITS = { prompt: 5, viral: 3 }; /* ══════════════════════════════════════ STATE ══════════════════════════════════════ */ var pgType = 'hook'; var vfFormula = 'shock'; var isPremium = ps2CheckPremium(); var pgTyping = false; var vfTyping = false; /* ══════════════════════════════════════ PREMIUM CHECK ══════════════════════════════════════ */ function ps2CheckPremium() { try { var data = JSON.parse(localStorage.getItem('ps2_premium') || 'null'); if (!data) return false; if (Date.now() > data.expiry) { localStorage.removeItem('ps2_premium'); return false; } return true; } catch(e) { return false; } } var VERIFY_API = 'https://adscoffee.vn/wp-json/adscoffee/v1/verify-license'; async function ps2ActivatePremium(code) { try { var res = await fetch(VERIFY_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: code, feature: 'ads_builder' }) }); var data = await res.json(); if (data.valid) { var expiry = Date.now() + 30 * 24 * 60 * 60 * 1000; localStorage.setItem('ps2_premium', JSON.stringify({ expiry: expiry, key: code })); isPremium = true; return true; } return false; } catch(e) { return false; } } window.ps2Upgrade = function() { var code = prompt('Nhập mã kích hoạt Premium (bạn nhận qua email sau khi thanh toán):\n\nChưa có mã? Bấm OK để đến trang thanh toán.'); if (!code) { window.open(PAYMENT_URL, '_blank'); return; } var trimmed = code.trim().toUpperCase(); // Show loading ps2ActivatePremium(trimmed).then(function(ok) { if (ok) { alert('✅ Kích hoạt thành công! Tận hưởng Premium!'); location.reload(); } else { alert('❌ Mã không hợp lệ. Kiểm tra lại email hoặc liên hệ support.'); window.open(PAYMENT_URL, '_blank'); } }); }; window.ps2ShowPaywall = function() { ps2Upgrade(); }; // Show premium forms if user is premium if (isPremium) { var psPaywall = document.getElementById('ps-paywall'); var psPremium = document.getElementById('ps-premium-content'); if (psPaywall) psPaywall.style.display = 'none'; if (psPremium) psPremium.style.display = 'block'; } /* ══════════════════════════════════════ TAB NAVIGATION ══════════════════════════════════════ */ window.ps2Tab = function(id, btn) { document.querySelectorAll('#ps2 .ps-panel').forEach(function(p){ p.classList.remove('active'); }); document.querySelectorAll('#ps2 .ps-tab').forEach(function(b){ b.classList.remove('active'); }); var panel = document.getElementById('panel-' + id); if (panel) panel.classList.add('active'); if (btn) btn.classList.add('active'); }; window.psSubTab = function(sub) { var adsBtn = document.getElementById('ps-sub-ads'); var calBtn = document.getElementById('ps-sub-cal'); var adsPanel = document.getElementById('ps-sub-panel-ads'); var calPanel = document.getElementById('ps-sub-panel-cal'); if (!adsBtn || !calBtn) return; if (sub === 'ads') { adsBtn.classList.add('active'); calBtn.classList.remove('active'); if (adsPanel) adsPanel.style.display = 'block'; if (calPanel) calPanel.style.display = 'none'; } else { calBtn.classList.add('active'); adsBtn.classList.remove('active'); if (calPanel) calPanel.style.display = 'block'; if (adsPanel) adsPanel.style.display = 'none'; } }; /* ══════════════════════════════════════ FREE USAGE TRACKING (localStorage) ══════════════════════════════════════ */ function getUsage(key) { try { var data = JSON.parse(localStorage.getItem('ps2_usage_' + key) || '{}'); var today = new Date().toDateString(); if (data.date !== today) return 0; return data.count || 0; } catch(e) { return 0; } } function incUsage(key) { var today = new Date().toDateString(); var count = getUsage(key) + 1; localStorage.setItem('ps2_usage_' + key, JSON.stringify({ date: today, count: count })); return count; } function checkLimit(key) { if (isPremium) return true; return getUsage(key) < FREE_LIMITS[key]; } function formatNum(n) { return n.toLocaleString('vi-VN') + 'đ'; } /* ══════════════════════════════════════ CHIP SELECTION ══════════════════════════════════════ */ document.querySelectorAll('#pg-chips .ps-chip').forEach(function(chip) { chip.addEventListener('click', function() { document.querySelectorAll('#pg-chips .ps-chip').forEach(function(c){ c.classList.remove('active'); }); chip.classList.add('active'); pgType = chip.dataset.type; }); }); document.querySelectorAll('#vf-grid .vf-card').forEach(function(card) { card.addEventListener('click', function() { document.querySelectorAll('#vf-grid .vf-card').forEach(function(c){ c.classList.remove('active'); }); card.classList.add('active'); vfFormula = card.dataset.formula; }); }); /* ══════════════════════════════════════ TYPEWRITER ══════════════════════════════════════ */ function psTypeWriter(el, text, speed, onDone) { el.innerHTML = ''; var i = 0; var timer = setInterval(function() { i++; var raw = text.slice(0, i); var fmt = raw .replace(/\[TẦNG [123] [—–][^\]]+\]/g, function(m){ return '' + m + ''; }) .replace(/HOOK \d+:|AIDA \d+:|PAS \d+:|STORY \d+:|VIRAL:|📌|🔵|🟡|🔴/g, function(m){ return '' + m + ''; }); el.innerHTML = fmt + ''; if (i >= text.length) { clearInterval(timer); setTimeout(function() { el.querySelectorAll('.ps-cursor').forEach(function(c){ c.style.display='none'; }); if (onDone) onDone(); }, 500); } }, speed); } /* ══════════════════════════════════════ COPY UTILITY ══════════════════════════════════════ */ window.psCopy = function(id, btn) { var text = document.getElementById(id).innerText; var orig = btn.innerHTML; var copy = function() { btn.innerHTML = '✅ Đã copy!'; setTimeout(function(){ btn.innerHTML = orig; }, 2000); }; if (navigator.clipboard) { navigator.clipboard.writeText(text).then(copy).catch(function(){ var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch(e){} document.body.removeChild(ta); copy(); }); } else { var ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch(e){} document.body.removeChild(ta); copy(); } }; /* ══════════════════════════════════════ PANEL 1: PROMPT GENERATOR ══════════════════════════════════════ */ function buildPrompt(type, product, audience, tone, count) { var p = product || '[Sản phẩm của bạn]'; var a = audience; var t = tone; var n = count; var t1 = '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nTarget: ' + a + '\nTone: ' + t; var t2 = '\n\n[TẦNG 2 — PERSONA]\nĐóng vai senior copywriter Facebook Ads 10 năm kinh nghiệm ngành giáo dục Việt Nam. Bạn đã test hơn 5,000 content và biết chính xác điều gì khiến phụ huynh DỪNG SCROLL.'; var t3 = '\n\n[TẦNG 3 — OUTPUT]\n'; var map = { hook: 'Viết ' + n + ' hook 3 giây cho ' + p + ':\n- ' + Math.ceil(n/3) + ' hook dạng câu hỏi phản trực giác (KHÔNG dùng "Bạn có biết")\n- ' + Math.ceil(n/3) + ' hook tuyên bố gây sốc / phản trực giác\n- ' + Math.floor(n/3) + ' hook kể chuyện 1 câu\nMỗi hook DƯỚI 15 từ. Phải khiến ' + a + ' DỪNG SCROLL.', aida: 'Viết ' + n + ' content Facebook Ads theo AIDA cho ' + p + ':\n- A (Attention): Hook 1 dòng gây tò mò\n- I (Interest): 2-3 câu mô tả vấn đề cụ thể của ' + a + '\n- D (Desire): 1-2 câu kích cảm xúc + 1 social proof có số liệu\n- A (Action): CTA cụ thể có urgency nhẹ\nMỗi version 80-120 từ. Highlight USP khác nhau ở mỗi version.', pas: 'Viết ' + n + ' content Facebook Ads theo PAS cho ' + p + ':\n- P (Problem): Nỗi đau CỤ THỂ — có tình huống thực tế, không generic\n- A (Agitate): Khoét sâu hậu quả — nhưng không gây cảm giác tội lỗi quá mức\n- S (Solution): Giới thiệu ' + p + ' là giải pháp + 1 bằng chứng\nMỗi version dùng 1 góc nỗi đau khác nhau.', story: 'Viết ' + Math.min(n, 3) + ' content Facebook Ads dạng storytelling cho ' + p + ':\nStory 1: ' + a + ' kể (ngôi 1) — chân thật\nStory 2: Trước-sau có số liệu cụ thể\nStory 3: Người trong cuộc (giáo viên/founder)\nCấu trúc: Hook 1 câu → Tình huống → Conflict → Giải pháp → Kết quả → CTA\n150-200 từ/story. Chi tiết Việt Nam.', cta: 'Viết 30 CTA cho ' + p + ' theo 3 stage funnel:\n\n🔵 TOP — Cold audience: 10 CTA khám phá (thấp commitment)\n🟡 MID — Warm audience: 10 CTA consideration (benefit cụ thể)\n🔴 HOT — Hot audience: 10 CTA conversion (urgency + scarcity)\n\nMỗi CTA dưới 8 từ. KHÔNG dùng "Đăng ký ngay" sáo rỗng.', carousel: 'Viết 1 Carousel Ads 5 cards cho ' + p + ':\nCard 1: Hook — gây tò mò nỗi đau\nCard 2: Problem — khoét sâu, có số liệu\nCard 3: Solution — giới thiệu ' + p + ' + USP chính\nCard 4: Proof — kết quả + social proof\nCard 5: CTA + offer cụ thể\nMỗi card: Tiêu đề (5-7 từ) + Mô tả (15-20 từ) + Headline link.\nFlow liên kết từ card 1→5.' }; t3 += (map[type] || map.hook); return t1 + t2 + t3; } window.pgGenerate = function() { if (pgTyping) return; if (!checkLimit('prompt')) { document.getElementById('pg-limit').style.display = 'flex'; document.getElementById('pg-used').textContent = FREE_LIMITS.prompt; return; } var product = document.getElementById('pg-product').value.trim(); if (!product) { var inp = document.getElementById('pg-product'); inp.style.borderColor = '#ff5f57'; inp.placeholder = '⚠️ Nhập tên sản phẩm trước nhé!'; setTimeout(function(){ inp.style.borderColor=''; inp.placeholder='VD: Khóa IELTS Junior...'; }, 2500); return; } pgTyping = true; var btn = document.getElementById('pg-btn'); document.getElementById('pg-btn-text').textContent = '⏳ Đang tạo...'; btn.disabled = true; var prompt = buildPrompt( pgType, product, document.getElementById('pg-audience').value, document.getElementById('pg-tone').value, parseInt(document.getElementById('pg-count').value) ); var output = document.getElementById('pg-output'); var outputText = document.getElementById('pg-output-text'); output.classList.remove('visible'); setTimeout(function() { output.classList.add('visible'); var speed = prompt.length > 500 ? 6 : 10; psTypeWriter(outputText, prompt, speed, function() { pgTyping = false; btn.disabled = false; document.getElementById('pg-btn-text').textContent = '✦ Tạo lại'; var used = incUsage('prompt'); var remaining = FREE_LIMITS.prompt - used; if (remaining <= 1 && !isPremium) { document.getElementById('pg-limit').style.display = 'flex'; document.getElementById('pg-used').textContent = used; } }); }, 400); }; document.getElementById('pg-product').addEventListener('keypress', function(e) { if (e.key === 'Enter') window.pgGenerate(); }); /* ══════════════════════════════════════ PANEL 2: BUDGET PLANNER ══════════════════════════════════════ */ // Benchmarks by type var BP_BENCHMARKS = { mamNon: { cpm:[45,65], ctr:[1.2,2.0], cpl:[400,700], cold:0.40, warm:0.30, hot:0.20, buf:0.10 }, tieuHoc: { cpm:[50,70], ctr:[1.5,2.5], cpl:[450,750], cold:0.38, warm:0.30, hot:0.22, buf:0.10 }, ielts: { cpm:[55,80], ctr:[1.5,2.5], cpl:[450,800], cold:0.35, warm:0.30, hot:0.25, buf:0.10 }, toeic: { cpm:[45,65], ctr:[1.3,2.2], cpl:[350,600], cold:0.38, warm:0.32, hot:0.20, buf:0.10 }, tiengAnh:{ cpm:[40,60], ctr:[1.2,2.0], cpl:[300,550], cold:0.40, warm:0.30, hot:0.20, buf:0.10 }, stem: { cpm:[50,75], ctr:[1.4,2.3], cpl:[400,700], cold:0.38, warm:0.28, hot:0.24, buf:0.10 }, truongQT:{ cpm:[70,120], ctr:[0.8,1.5], cpl:[800,1500], cold:0.35, warm:0.28, hot:0.27, buf:0.10 }, online: { cpm:[35,55], ctr:[1.5,2.8], cpl:[250,500], cold:0.42, warm:0.28, hot:0.20, buf:0.10 }, }; // Area adjustments var BP_AREA = { hcm: 1.15, hn: 1.10, dn: 0.90, other: 0.85 }; window.bpCalculate = function() { var budget = parseInt(document.getElementById('bp-budget').value); var type = document.getElementById('bp-type').value; var area = document.getElementById('bp-area').value; var bm = BP_BENCHMARKS[type] || BP_BENCHMARKS.ielts; var aFactor = BP_AREA[area] || 1; var cold = Math.round(budget * bm.cold); var warm = Math.round(budget * bm.warm); var hot = Math.round(budget * bm.hot); var buf = Math.round(budget * bm.buf); var cpmAvg = Math.round((bm.cpm[0] + bm.cpm[1]) / 2 * aFactor * 1000); var ctrAvg = ((bm.ctr[0] + bm.ctr[1]) / 2).toFixed(1); var cplLow = Math.round(bm.cpl[0] * aFactor); var cplHigh= Math.round(bm.cpl[1] * aFactor); var leadsLow = Math.floor(budget / cplHigh); var leadsHigh= Math.floor(budget / cplLow); var daily = Math.round(budget / 30); document.getElementById('bp-cold').textContent = (cold/1e6).toFixed(1) + 'tr'; document.getElementById('bp-warm').textContent = (warm/1e6).toFixed(1) + 'tr'; document.getElementById('bp-hot').textContent = (hot/1e6).toFixed(1) + 'tr'; document.getElementById('bp-buf').textContent = (buf/1e6).toFixed(1) + 'tr'; document.getElementById('bp-cpm').textContent = cpmAvg.toLocaleString('vi') + 'đ / 1000 imp'; document.getElementById('bp-ctr').textContent = '≥ ' + ctrAvg + '%'; document.getElementById('bp-cpl').textContent = (cplLow/1000)+'k – '+(cplHigh/1000)+'kđ / lead'; document.getElementById('bp-leads').textContent= leadsLow + ' – ' + leadsHigh + ' leads'; document.getElementById('bp-daily').textContent= daily.toLocaleString('vi') + 'đ / ngày'; // Warning for small budget var warn = document.getElementById('bp-warn'); if (budget < 5000000) { warn.style.display = 'block'; warn.textContent = '⚠️ Ngân sách dưới 5 triệu/tháng có thể chưa đủ để Facebook thuật toán học. Khuyến nghị: bắt đầu tối thiểu 5-10 triệu/tháng để có kết quả ổn định.'; } else if (budget < 10000000 && (type === 'truongQT')) { warn.style.display = 'block'; warn.textContent = '⚠️ Với Trường Quốc tế, CPM và CPL cao hơn trung bình. Ngân sách 10-20 triệu/tháng sẽ cho kết quả tốt hơn đáng kể.'; } else { warn.style.display = 'none'; } var result = document.getElementById('bp-result'); result.classList.add('visible'); result.scrollIntoView({ behavior:'smooth', block:'nearest' }); }; /* ══════════════════════════════════════ PANEL 3: VIRAL FORMULA ══════════════════════════════════════ */ var VF_TEMPLATES = { shock: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Shock & Reveal\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter viral content chuyên ngành giáo dục Việt Nam. Bạn biết cách viết content gây SỐC nhưng không phản cảm — khiến người đọc phải share ngay.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo formula Shock & Reveal cho ' + p + ':\n\nCấu trúc:\n① SỐ LIỆU GÂY SỐC (liên quan đến "' + pain + '")\n② SỰ THẬT ẨN GIẤU mà phụ huynh không biết\n③ GIẢI PHÁP: ' + p + ' giải quyết điều đó thế nào\n④ CTA nhẹ nhàng\n\nMỗi content 100-150 từ. Số liệu phải credible. Không clickbait rẻ tiền.'; }, curiosity: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Curiosity Gap\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter chuyên tạo content "không thể không đọc tiếp". Bạn giỏi tạo khoảng trống thông tin khiến não bộ phải tìm câu trả lời.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo Curiosity Gap cho ' + p + ':\n\nCấu trúc:\n① Hook tạo câu hỏi: "Lý do thật sự khiến [liên quan đến ' + pain + ']..."\n② Kéo dài sự tò mò — đừng trả lời ngay\n③ Tiết lộ từng phần\n④ ' + p + ' là giải pháp\n⑤ CTA xem thêm\n\nMỗi content khiến người đọc PHẢI cuộn xuống để tìm câu trả lời.'; }, social: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Social Proof Stack\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter chuyên tạo content social proof. Bạn biết rằng người Việt Nam quyết định theo cộng đồng — ai cũng làm thì mình cũng làm.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo Social Proof Stack cho ' + p + ':\n\nCấu trúc:\n① Mở đầu: "[Số] phụ huynh/gia đình đã [hành động]"\n② Stack thêm: từ X tăng lên Y trong Z tháng\n③ Mini story ngắn của 1 phụ huynh (có tên, quận)\n④ Gợi ý: bạn cũng có thể làm điều tương tự\n⑤ CTA\n\nSố liệu phải credible và cụ thể. Tên địa danh Việt Nam.'; }, before: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Before/After Bridge\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter transformation story. Bạn biết não người phản ứng mạnh với sự tương phản — trước và sau.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo Before/After Bridge cho ' + p + ':\n\nCấu trúc:\n① BEFORE: Mô tả cụ thể tình trạng đau — liên quan đến "' + pain + '"\n② BRIDGE: Điều gì thay đổi? Khi nào? Tại sao?\n③ AFTER: Kết quả cụ thể — có số liệu, cảm xúc thật\n④ ' + p + ' là cầu nối\n⑤ CTA\n\n"Trước" phải đủ đau. "Sau" phải đủ khao khát. "Bridge" phải credible.'; }, fear: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Fear + Relief\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter emotional intelligence. Bạn biết kích hoạt nỗi sợ đúng mức — không gây hoảng loạn, chỉ tạo đủ tension để người đọc muốn tìm giải pháp.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo Fear + Relief cho ' + p + ':\n\nCấu trúc:\n① NỖI SỢ: Mô tả hậu quả nếu không giải quyết "' + pain + '"\n② KHOÉT SÂU: Điều gì xảy ra về lâu dài?\n③ NHƯNG: Có cách thoát khỏi điều đó\n④ RELIEF: ' + p + ' giải quyết cụ thể thế nào\n⑤ CTA nhẹ nhàng\n\nTone đồng cảm, không phán xét. Fear vừa đủ — không gây lo âu quá mức.'; }, insider: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: Insider Secret\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter insider content. Bạn tạo cảm giác người đọc đang được tiết lộ thông tin "nội bộ" — điều mà người khác không biết.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo Insider Secret cho ' + p + ':\n\nCấu trúc:\n① Hook: "Điều mà [X]% phụ huynh không biết về [liên quan đến ' + pain + ']"\n② BÍ MẬT NỘI BỘ: Thông tin/insight thật sự có giá trị\n③ Tại sao điều này quan trọng với con bạn\n④ ' + p + ' ứng dụng điều này như thế nào\n⑤ CTA "xem thêm"\n\nInsider info phải credible và genuinely valuable. Không clickbait.'; }, challenge: function(p, pain) { return '[TẦNG 1 — NGỮ CẢNH]\nSản phẩm: ' + p + '\nFormula: 7-Day Challenge\nNỗi đau: ' + pain + '\n\n[TẦNG 2 — PERSONA]\nĐóng vai copywriter engagement content. Bạn biết tạo micro-commitment — khi người ta cam kết thử 7 ngày, xác suất convert cao gấp 3 lần.\n\n[TẦNG 3 — OUTPUT]\nViết 3 content Facebook Ads theo 7-Day Challenge cho ' + p + ':\n\nCấu trúc:\n① Hook: "Thử điều này trong 7 ngày — và tự thấy sự khác biệt"\n② CHALLENGE: Hành động cụ thể hàng ngày (ngày 1, 3, 7)\n③ KỲ VỌNG: Sau 7 ngày sẽ thấy gì?\n④ ' + p + ' hỗ trợ challenge đó\n⑤ CTA: "Bắt đầu ngay hôm nay"\n\nChallenge phải đủ dễ để bắt đầu, đủ có ý nghĩa để tiếp tục.'; } }; window.vfGenerate = function() { if (vfTyping) return; if (!checkLimit('viral')) { document.getElementById('vf-limit').style.display = 'flex'; document.getElementById('vf-used').textContent = FREE_LIMITS.viral; return; } var product = document.getElementById('vf-product').value.trim(); var pain = document.getElementById('vf-pain').value.trim(); if (!product || !pain) { var target = !product ? 'vf-product' : 'vf-pain'; var inp = document.getElementById(target); inp.style.borderColor = '#ff5f57'; setTimeout(function(){ inp.style.borderColor=''; }, 2500); return; } vfTyping = true; var btn = document.getElementById('vf-btn'); document.getElementById('vf-btn-text').textContent = '⏳ Đang tạo...'; btn.disabled = true; var builder = VF_TEMPLATES[vfFormula] || VF_TEMPLATES.shock; var prompt = builder(product, pain); var output = document.getElementById('vf-output'); var outputText = document.getElementById('vf-output-text'); output.classList.remove('visible'); setTimeout(function() { output.classList.add('visible'); psTypeWriter(outputText, prompt, 7, function() { vfTyping = false; btn.disabled = false; document.getElementById('vf-btn-text').textContent = '🔥 Tạo lại'; var used = incUsage('viral'); if (used >= FREE_LIMITS.viral && !isPremium) { document.getElementById('vf-limit').style.display = 'flex'; document.getElementById('vf-used').textContent = used; } }); }, 400); }; /* ══════════════════════════════════════ PANEL 4: ADS BUILDER AI (Claude API) GỌI QUA ANTHROPIC API PROXY ══════════════════════════════════════ */ window.abGenerate = async function() { if (!isPremium) { ps2ShowPaywall(); return; } var name = document.getElementById('ab-name').value.trim(); var type = document.getElementById('ab-type').value; var price = document.getElementById('ab-price').value.trim(); var area = document.getElementById('ab-area').value.trim(); var usp = document.getElementById('ab-usp').value.trim(); var pain = document.getElementById('ab-pain').value.trim(); var budget = document.getElementById('ab-budget').value; var goal = document.getElementById('ab-goal').value.trim(); var cta = document.getElementById('ab-cta').value.trim(); if (!name || !usp || !pain) { alert('Vui lòng điền đầy đủ: Tên trường, USP và Nỗi đau khách hàng.'); return; } var btn = document.getElementById('ab-btn'); document.getElementById('ab-btn-text').textContent = '⏳ AI đang tạo campaign...'; btn.disabled = true; var output = document.getElementById('ab-output'); var outputText = document.getElementById('ab-output-text'); output.classList.remove('visible'); output.classList.add('visible'); outputText.innerHTML = '

Claude AI đang phân tích và tạo campaign...
Thường mất 15-25 giây
'; var systemPrompt = 'Bạn là senior Performance Marketer với 10 năm kinh nghiệm chạy Facebook Ads cho ngành giáo dục tại Việt Nam. Viết content ads THỰC CHIẾN, không generic, đánh trúng tâm lý phụ huynh Việt Nam.'; var userPrompt = 'Tạo FULL CAMPAIGN Facebook Ads cho:\n' + '- Tên: ' + name + '\n' + '- Loại: ' + type + '\n' + '- Học phí: ' + price + '\n' + '- Khu vực: ' + area + '\n' + '- USP: ' + usp + '\n' + '- Nỗi đau phụ huynh: ' + pain + '\n' + '- Ngân sách ads: ' + budget + '/tháng\n' + '- Mục tiêu: ' + goal + '\n' + '- CTA: ' + cta + '\n\n' + 'Hãy tạo đầy đủ:\n' + '## 🎯 3 HOOK (Cold/Warm/Hot audience)\n' + '## 📝 2 CONTENT AIDA ĐẦY ĐỦ (80-120 từ mỗi cái)\n' + '## 💔 1 CONTENT PAS (đánh vào nỗi đau: ' + pain + ')\n' + '## 🔥 10 CTA THEO FUNNEL (3 Cold + 4 Warm + 3 Hot)\n' + '## 🎯 GỢI Ý TARGET AUDIENCE (demographic + interest + behavior)\n' + '## 💰 PHÂN CHIA NGÂN SẬT ĐỀ XUẤT\n\n' + 'Output bằng tiếng Việt. Cụ thể, thực chiến, không sáo rỗng.'; try { var ps2Key = ''; try { var ps2d = JSON.parse(localStorage.getItem('ps2_premium')||'null'); if(ps2d) ps2Key = ps2d.key||''; } catch(e){} var response = await fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: ps2Key, feature: 'ads_builder', system: systemPrompt, user: userPrompt }) }); var data = await response.json(); var text = ''; if (data.content && data.content[0]) { text = data.content[0].text || ''; } else if (data.error) { text = '❌ Lỗi API: ' + data.error; } outputText.innerHTML = ''; psTypeWriter(outputText, text, 5, function() { btn.disabled = false; document.getElementById('ab-btn-text').textContent = '⭐ Tạo lại Campaign'; }); } catch(err) { outputText.innerHTML = '❌ Không thể kết nối API. Vui lòng thử lại hoặc liên hệ support.'; btn.disabled = false; document.getElementById('ab-btn-text').textContent = '⭐ Tạo lại Campaign'; } }; /* ══════════════════════════════════════ PANEL 5: CONTENT CALENDAR AI ══════════════════════════════════════ */ window.calGenerate = async function() { if (!isPremium) { ps2ShowPaywall(); return; } var brand = document.getElementById('cal-brand').value.trim(); var month = document.getElementById('cal-month').value; var type = document.getElementById('cal-type').value; var event = document.getElementById('cal-event').value.trim(); if (!brand) { alert('Vui lòng nhập tên thương hiệu.'); return; } var btn = document.getElementById('cal-btn'); document.getElementById('cal-btn-text').textContent = '⏳ AI đang tạo lịch...'; btn.disabled = true; var output = document.getElementById('cal-output'); var outputText = document.getElementById('cal-output-text'); output.classList.remove('visible'); output.classList.add('visible'); outputText.innerHTML = '

Claude AI đang lập lịch content 30 ngày...
'; var userPrompt = 'Tạo lịch content Facebook/Instagram 30 ngày cho:\n' + '- Thương hiệu: ' + brand + '\n' + '- Loại hình: ' + type + '\n' + '- Tháng: ' + month + '\n' + (event ? '- Sự kiện đặc biệt: ' + event + '\n' : '') + '\nTạo 18-20 bài đăng, phân bổ đều trong tháng. Với mỗi bài:\n' + 'Ngày X | Format (Feed/Reel/Story/Carousel) | Chủ đề | Caption gợi ý (2-3 câu) | Giờ đăng tốt\n\n' + 'Mix các loại: Awareness, Educational, Social Proof, Promotional, Behind-the-scenes, FAQ.\n' + 'Tích hợp ngày lễ/sự kiện Việt Nam tháng ' + month + '.\n' + 'Output dạng bảng dễ copy vào Google Sheets. Tiếng Việt.'; try { var calKey = ''; try { var cald = JSON.parse(localStorage.getItem('ps2_premium')||'null'); if(cald) calKey = cald.key||''; } catch(e){} var response = await fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: calKey, feature: 'calendar', system: 'Bạn là content strategist chuyên ngành giáo dục Việt Nam. Tạo lịch content thực tế, đa dạng format, phù hợp thuật toán mạng xã hội Việt Nam.', user: userPrompt }) }); var data = await response.json(); var text = data.content && data.content[0] ? data.content[0].text : '❌ Lỗi: ' + (data.error || 'Unknown'); outputText.innerHTML = ''; psTypeWriter(outputText, text, 4, function() { btn.disabled = false; document.getElementById('cal-btn-text').textContent = '📅 Tạo lại Lịch'; }); } catch(err) { outputText.innerHTML = '❌ Lỗi kết nối. Thử lại sau.'; btn.disabled = false; document.getElementById('cal-btn-text').textContent = '📅 Tạo lại Lịch'; } }; /* ══════════════════════════════════════ PANEL 6: SEO WRITER AI (Premium 350k) ══════════════════════════════════════ */ // Premium check riêng cho SEO Writer (mã khác 250k) var SW_PAYMENT = 'https://adscoffee.vn/san-pham/seo-writer-ai-viet-bai-chuan-yoast-aio-geo/'; function swIsPremium() { // Chỉ mở nếu có mã SEO Writer (#838) hoặc Bundle (#839) riêng // Mã Prompt Studio Premium (#837) KHÔNG bao gồm SEO Writer try { var d = JSON.parse(localStorage.getItem('sw_premium') || 'null'); if (!d) return false; if (Date.now() > d.expiry) { localStorage.removeItem('sw_premium'); return false; } return true; } catch(e) { return false; } } window.swUpgrade = function() { var code = prompt('Nhập mã kích hoạt SEO Writer Premium 350k:\n(Nhận qua email sau khi thanh toán)\n\nChưa có mã? Bấm OK để đến trang thanh toán.'); if (!code) { window.open(SW_PAYMENT, '_blank'); return; } var c = code.trim().toUpperCase(); fetch(VERIFY_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: c, feature: 'seo_writer' }) }) .then(function(r){ return r.json(); }) .then(function(data) { if (data.valid) { var exp = Date.now() + 30*24*60*60*1000; localStorage.setItem('sw_premium', JSON.stringify({ expiry: exp, key: c })); alert('✅ Kích hoạt SEO Writer AI thành công!'); location.reload(); } else { alert('❌ ' + (data.message || 'Mã không hợp lệ. Kiểm tra email hoặc liên hệ support.')); window.open(SW_PAYMENT, '_blank'); } }) .catch(function() { alert('❌ Lỗi kết nối. Vui lòng thử lại.'); }); }; // Init SEO Writer premium state (function() { if (swIsPremium()) { var pw = document.getElementById('sw-paywall'); var fm = document.getElementById('sw-form'); if (pw) pw.style.display = 'none'; if (fm) fm.style.display = 'block'; } })(); // Char counters window.swCntTitle = function(el) { var n = el.value.length; var cnt = document.getElementById('sw-tcnt'); if (cnt) { cnt.textContent = n+'/60'; cnt.style.color = n>=50&&n<=60?'#6dc35d':n>60?'#f87171':'#f59e0b'; } }; window.swCntMeta = function(el) { var n = el.value.length; var cnt = document.getElementById('sw-mcnt'); if (cnt) { cnt.textContent = n+'/155'; cnt.style.color = n>=120&&n<=155?'#6dc35d':n>155?'#f87171':'#f59e0b'; } }; // Output tabs window.swOTab = function(id, btn) { document.querySelectorAll('#panel-seowriter .sw-opanel').forEach(function(p){ p.classList.remove('active'); }); document.querySelectorAll('#panel-seowriter .sw-otab').forEach(function(b){ b.classList.remove('active'); }); var p = document.getElementById('sw-op-'+id); if (p) p.classList.add('active'); if (btn) btn.classList.add('active'); }; // Typewriter for SEO Writer function swType(el, text, speed, onDone) { el.innerHTML = ''; var i = 0; var timer = setInterval(function(){ i += 4; var raw = text.slice(0, i); var fmt = raw .replace(/(^|\n)(# .+)/g, '$1$2') .replace(/(^|\n)(## .+)/g, '$1$2') .replace(/(^|\n)(### .+)/g, '$1$3') .replace(/(\[toc\]|\[TABLE_OF_CONTENTS\])/g, '$1') .replace(/(SEO Title:|Meta Description:|Focus Keyword:|Slug gợi ý:)/g, '$1') .replace(/(❓ \*\*[^*]+\*\*|Câu hỏi \d+:|FAQ:)/g, '$1'); el.innerHTML = fmt + (i < text.length ? '' : ''); if (i >= text.length) { clearInterval(timer); el.innerHTML = fmt; if (onDone) onDone(); } }, speed); } // Copy article window.swCopyArt = function() { var text = document.getElementById('sw-art-text').innerText; var btn = document.getElementById('sw-art-copybtn'); var orig = btn.textContent; var done = function(){ btn.textContent='✅ Đã copy!'; setTimeout(function(){ btn.textContent=orig; }, 2000); }; if (navigator.clipboard) { navigator.clipboard.writeText(text).then(done).catch(function(){ var ta=document.createElement('textarea'); ta.value=text; document.body.appendChild(ta); ta.select(); try{document.execCommand('copy');}catch(e){} document.body.removeChild(ta); done(); }); } else { var ta=document.createElement('textarea'); ta.value=text; document.body.appendChild(ta); ta.select(); try{document.execCommand('copy');}catch(e){} document.body.removeChild(ta); done(); } }; // Render checklist result function swRenderChk(kw, tl, ml, wc) { var kwTarget = Math.round(wc * 0.015); var rows = [ { i:'✅', l:'Focus Keyword: "'+kw+'"', s:'Đã thiết lập', c:'cok' }, { i:'✅', l:'Keyword trong SEO Title', s:'Đúng chuẩn Yoast', c:'cok' }, { i: tl>=50&&tl<=60?'✅':'⚠️', l:'SEO Title: '+tl+'/60 ký tự', s: tl>=50&&tl<=60?'Tối ưu ✅':'Cần điều chỉnh', c: tl>=50&&tl<=60?'cok':'cwarn' }, { i: ml>=120&&ml<=155?'✅':'⚠️', l:'Meta Description: '+ml+'/155 ký tự', s: ml>=120?'Tối ưu':'Nên dài hơn', c: ml>=120?'cok':'cwarn' }, { i:'✅', l:'H1 chứa focus keyword', s:'1 H1 duy nhất', c:'cok' }, { i:'✅', l:'Keyword trong 150 từ đầu', s:'Answer Box đã có', c:'cok' }, { i:'✅', l:'Mật độ keyword ~1.5%', s:'~'+kwTarget+' lần / '+wc+' từ', c:'cok' }, { i:'✅', l:'H2/H3 hierarchy đúng', s:'Không skip heading level', c:'cok' }, { i:'✅', l:'Đoạn văn ≤ 150 từ', s:'Flesch Kincaid friendly', c:'cok' }, { i:'⭐', l:'[toc] shortcode đã thêm', s:'Cài Easy Table of Contents', c:'cinfo' }, { i:'⭐', l:'FAQ Schema (7 câu hỏi)', s:'Rich Snippet ready', c:'cinfo' }, { i:'⚠️', l:'Featured Image', s:'Cần thêm thủ công sau khi paste', c:'cwarn' }, { i:'⚠️', l:'Alt text ảnh chứa keyword', s:'Thêm khi upload ảnh vào WP', c:'cwarn' }, { i:'✅', l:'Internal links đã gợi ý', s:'Thay URL thật của bạn', c:'cok' }, { i:'✅', l:'AIO Answer Box', s:'2-3 câu trả lời trực tiếp', c:'cok' }, { i:'✅', l:'GEO: Structured format', s:'Tối ưu Google SGE / Gemini', c:'cok' }, ]; var html = rows.map(function(r){ return '
'+r.i+''+r.l+''+r.s+'
'; }).join(''); document.getElementById('sw-chk-items').innerHTML = html; } // Render tips function swRenderTips(kw) { var tips = [ { cls:'tg', h:'✅ Sau khi paste vào WordPress — làm ngay 5 việc', b: '1. Upload Featured Image (1200×630px) → Alt Text chứa "'+kw+'"
'+ '2. Cài Easy Table of Contents → [toc] tự render
'+ '3. Kiểm tra Yoast panel → đèn xanh tất cả trước khi Publish
'+ '4. Thay [URL_BÀI_LIÊN_QUAN] bằng URL thật
'+ '5. Đặt Category, Tags và Featured Image' }, { cls:'ta', h:'⚠️ Những lỗi Yoast phổ biến hay mắc phải', b: '• Mật độ quá thấp (đèn đỏ): Keyword < 0.5% → thêm vào H3, đoạn body
'+ '• Keyword stuffing: > 2.5% → Yoast phạt, Google cũng phạt
'+ '• 2 H1 trong bài: Theme đôi khi tự thêm H1 — kiểm tra Inspector
'+ '• Meta rỗng: Google tự tạo → không tối ưu, luôn điền thủ công
'+ '• Skip heading: H2→H4 (bỏ H3) → Yoast cảnh báo structure' }, { cls:'tb', h:'🤖 AIO Tips — Để AI Chatbot trích dẫn bài bạn', b: '• Answer Box đầu bài: 2-3 câu trả lời trực tiếp → ChatGPT/Claude hay trích
'+ '• Định nghĩa rõ: "[Keyword] là..." → format AI ưu tiên nhất
'+ '• Bullet points: List format rõ → AI dễ parse và trích dẫn
'+ '• Số liệu cụ thể: "CTR tăng 45%" > "CTR tăng đáng kể"
'+ '• Entity mentions: Đề cập ChatGPT, Claude, Google → tăng topical authority' }, { cls:'tp', h:'⭐ GEO Tips — Tối ưu cho Google SGE / Gemini Search', b: '• FAQ section: Giúp xuất hiện trong AI Overview của Google
'+ '• E-E-A-T: Thêm tên tác giả + bio + ngày cập nhật → Google tin tưởng
'+ '• Cite sources: Link đến nguồn uy tín (Google Blog, Meta, Statista)
'+ '• Schema markup: Article + FAQ + Author → Rich Snippet + AI Overview
'+ '• Cập nhật định kỳ: Bài 2026 → Yoast hiển thị badge → Google ưu tiên' }, { cls:'tg', h:'📅 Plugins cần cài để đạt điểm tối đa', b: '① Easy Table of Contents (free) → TOC tự động, +1 điểm Yoast
'+ '② Yoast SEO (bản free đủ dùng) → Checklist đầy đủ
'+ '③ Rank Math SEO (thay thế Yoast) → AI suggestions, thân thiện hơn
'+ '④ Schema & Structured Data → FAQ Rich Snippet tự động
'+ '⑤ WP Rocket → Page speed → Core Web Vitals → SEO bonus' }, ]; var html = tips.map(function(t){ return '
'+t.h+'
'+t.b+'
'; }).join(''); document.getElementById('sw-tips-items').innerHTML = html; } // Main generate window.swGenerate = async function() { if (!swIsPremium()) { swUpgrade(); return; } var kw = document.getElementById('sw-kw').value.trim(); if (!kw) { var inp = document.getElementById('sw-kw'); inp.style.borderColor = '#f87171'; inp.placeholder = '⚠️ Nhập Focus Keyword trước!'; setTimeout(function(){ inp.style.borderColor=''; inp.placeholder='VD: cách viết content facebook ads bằng chatgpt'; }, 2500); return; } var title = document.getElementById('sw-title').value.trim(); var meta = document.getElementById('sw-meta').value.trim(); var niche = document.getElementById('sw-niche').value; var len = document.getElementById('sw-len').value; var outline = document.getElementById('sw-outline').value.trim(); var aud = document.getElementById('sw-aud').value; var tone = document.getElementById('sw-tone').value; var faq = document.getElementById('sw-faq').value; var toc = document.getElementById('sw-toc').value; var links = document.getElementById('sw-links').value; var related = document.getElementById('sw-related').value.trim(); var btn = document.getElementById('sw-gen-btn'); document.getElementById('sw-gtext').textContent = '⏳ AI đang viết bài...'; btn.disabled = true; var out = document.getElementById('sw-out'); var artEl = document.getElementById('sw-art-text'); out.classList.remove('visible'); out.classList.add('visible'); artEl.innerHTML = '

Claude AI đang viết bài SEO (~'+len+' từ)...
✓ Phân tích keyword "'+kw+'"⚡ Tạo cấu trúc H1/H2/H3 chuẩn Yoast...○ Viết nội dung mật độ 1-2%...○ Tạo FAQ Schema '+faq+' câu...○ Tối ưu AIO/GEO...
'; var systemP = 'Bạn là SEO Content Writer chuyên nghiệp tại Việt Nam, 8+ năm kinh nghiệm viết bài SEO cho ngành giáo dục và digital marketing. Bạn nắm vững Yoast SEO, AIO và GEO. Viết bài THỰC CHIẾN, có số liệu, ví dụ cụ thể — không sáo rỗng. Đảm bảo mật độ keyword 1-2%. Output phải đạt 7-8/10 Yoast.'; var kwCount = Math.round(parseInt(len)*0.015); var userP = [ '# Viết bài SEO hoàn chỉnh chuẩn Yoast + AIO/GEO\n', '## THÔNG TIN:', 'Focus Keyword: "'+kw+'"', title ? 'SEO Title: '+title : 'SEO Title: Tự tạo (50-60 ký tự, keyword đầu tiêu đề)', meta ? 'Meta Description: '+meta : 'Meta Description: Tự tạo (120-155 ký tự, có keyword và CTA)', 'Ngành: '+niche+' | Độ dài: ~'+len+' từ | Audience: '+aud+' | Tone: '+tone, 'FAQ: '+faq+' câu | TOC: '+(toc==='yes'?'Có [toc]':'Không')+' | Internal links: '+links+(related?' → URL: '+related:''), outline ? '\nOutline:\n'+outline : '', '\n## CẤU TRÚC OUTPUT (theo đúng thứ tự):', '```\nSEO Title: [50-60 ký tự, keyword ở đầu]\nMeta Description: [120-155 ký tự, keyword + CTA]\nFocus Keyword: '+kw+'\nSlug: [url-than-thien]\n```', toc==='yes' ? '[toc]\n' : '', '# [H1: tiêu đề bài chứa "'+kw+'", duy nhất 1 H1]\n', '**📌 Trả lời nhanh:** [2-3 câu trực tiếp chứa keyword — AIO trích đoạn này]\n', '[Các H2/H3 theo outline hoặc logic bài — mỗi đoạn ≤ 150 từ]\n', '[Internal links: '+links+' link với anchor text tự nhiên có keyword]\n', '## Câu hỏi thường gặp (FAQ)\n', '['+faq+' cặp Q&A:]\n❓ **[Câu hỏi liên quan keyword]?**\n💡 [Trả lời 2-4 câu, Rich Snippet ready]\n', '## Kết luận\n[Tóm tắt + CTA nội bộ]\n', '## YÊU CẦU KỸ THUẬT:', '1. Mật độ "'+kw+'": đúng 1-2% ('+len+' từ → '+kwCount+'-'+Math.round(parseInt(len)*0.02)+' lần)', '2. Keyword trong: H1, 150 từ đầu, ít nhất 1 H2, kết luận', '3. 1 H1 duy nhất — không tạo thêm H1', '4. H2/H3 đúng thứ bậc — không skip heading', '5. Đoạn văn ≤ 150 từ — Flesch Kincaid', '6. Tiếng Việt tự nhiên — không dịch máy', '7. Số liệu/ví dụ cụ thể từ thị trường Việt Nam', '8. AIO: Câu trả lời structured — AI chatbot có thể trích', '9. GEO: Đề cập ChatGPT, Claude, Google, Meta (entity mentions)', ].join('\n'); try { var swKey = ''; try { var swd = JSON.parse(localStorage.getItem('sw_premium')||'null'); if(swd) swKey = swd.key||''; if(!swKey) { var ps2d2 = JSON.parse(localStorage.getItem('ps2_premium')||'null'); if(ps2d2) swKey = ps2d2.key||''; } } catch(e){} var res = await fetch(API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_key: swKey, feature: 'seo_writer', system: systemP, user: userP }) }); var data = await res.json(); var text = data.content && data.content[0] ? data.content[0].text : '❌ Lỗi: '+(data.error||'Unknown error'); var wc = text.split(/\s+/).length; var tl = title.length || 55; var ml = meta.length || 130; swType(artEl, text, 4, function() { btn.disabled = false; document.getElementById('sw-gtext').textContent = '✍️ Viết lại bài'; // Score var sc = 7.0; if (tl>=50&&tl<=60) sc+=0.3; if (ml>=120&&ml<=155) sc+=0.3; if (parseInt(faq)>=5) sc+=0.2; if (toc==='yes') sc+=0.1; sc = Math.min(sc,8.2).toFixed(1); var pct = parseFloat(sc)/10*100; var ring = document.getElementById('sw-ring'); if (ring) ring.style.background='conic-gradient(#6dc35d 0% '+pct+'%, #1a1a1a '+pct+'%)'; var rv = document.getElementById('sw-rval'); if (rv) rv.textContent = sc; swRenderChk(kw, tl, ml, wc); swRenderTips(kw); }); } catch(err) { artEl.innerHTML = '❌ Không thể kết nối API. Thử lại hoặc liên hệ support@adscoffee.vn'; btn.disabled = false; document.getElementById('sw-gtext').textContent = '✍️ Viết bài SEO với AI'; } }; })(); // ══ BEAUTIFUL MODAL + SOFT LOCK ══ // ═══════════════════════════════════════════════════════ // ADSCOFFEE — BEAUTIFUL LICENSE MODAL + SOFT DEVICE LOCK // Thay thế toàn bộ ps2Upgrade, swUpgrade, ps2ShowPaywall // ═══════════════════════════════════════════════════════ // ── Device fingerprint (Soft Lock) ── function acGetDeviceId() { var id = localStorage.getItem('ac_device_id'); if (!id) { id = 'DEV-' + Date.now().toString(36).toUpperCase() + '-' + Math.random().toString(36).substr(2,6).toUpperCase(); localStorage.setItem('ac_device_id', id); } return id; } // ── Modal HTML ── (function injectModal() { var html = `
🔐
Kích hoạt tính năng
Nhập mã nhận qua email sau khi thanh toán.
⚠️ Mã này đang được dùng trên thiết bị khác. Xác nhận để chuyển sang thiết bị này — thiết bị cũ sẽ tự động bị khóa.
hoặc
Prompt Studio Premium
250.000 ₫ / tháng
PRO
✓Ads Builder AI + Calendar AI
✓Claude AI thật — không giới hạn lượt dùng
✓Mã gửi qua email ngay sau thanh toán
✓Hỗ trợ qua Facebook Page AdsCoffee
🛒 Nâng cấp ngay
đã thanh toán?
`; var wrap = document.createElement('div'); wrap.innerHTML = html; document.body.appendChild(wrap); // Close on overlay click document.getElementById('ac-lm-overlay').addEventListener('click', function(e){ if (e.target === this) acLmClose(); }); // ESC key document.addEventListener('keydown', function(e){ if (e.key === 'Escape') acLmClose(); }); })(); // ── Modal state ── var acLmFeature = null; var acLmForceDevice = false; var AC_LM_CONFIGS = { ads_builder: { icon: '🚀', title: 'Kích hoạt Ads Builder AI', sub: 'Nhập mã nhận qua email sau khi thanh toán.', pname: 'Prompt Studio Premium', pval: '379.000', url: '/san-pham/prompt-studio-premium-ads-builder-ai-content-calendar-ai/', feats: ['Ads Builder AI + Calendar AI','Claude AI thật — không giới hạn lượt','Mã gửi qua email ngay sau thanh toán','Hỗ trợ qua Facebook Page AdsCoffee'], storage: 'ps2_premium', lm_feature: 'ads_builder' }, calendar: { icon: '📅', title: 'Kích hoạt Calendar AI', sub: 'Nhập mã nhận qua email sau khi thanh toán.', pname: 'Prompt Studio Premium', pval: '379.000', url: '/san-pham/prompt-studio-premium-ads-builder-ai-content-calendar-ai/', feats: ['Ads Builder AI + Calendar AI','Lịch content 30 ngày chi tiết','Caption + format + giờ đăng tối ưu','Hỗ trợ qua Facebook Page AdsCoffee'], storage: 'ps2_premium', lm_feature: 'calendar' }, seo_writer: { icon: '✍️', title: 'Kích hoạt SEO Writer AI', sub: 'Nhập mã nhận qua email sau khi thanh toán.', pname: 'SEO Writer AI', pval: '350.000', url: '/san-pham/seo-writer-ai-viet-bai-chuan-yoast-aio-geo/', feats: ['Bài viết 1,500-2,500 từ chuẩn Yoast','SEO Title + Meta + Slug tối ưu','FAQ Schema + Internal links gợi ý','Output 7-8/10 Yoast ngay lần đầu'], storage: 'sw_premium', lm_feature: 'seo_writer' } }; window.acLmOpen = function(feature) { acLmFeature = feature; acLmForceDevice = false; var cfg = AC_LM_CONFIGS[feature]; if (!cfg) return; // Update UI document.getElementById('ac-lm-icon').textContent = cfg.icon; document.getElementById('ac-lm-title').textContent = cfg.title; document.getElementById('ac-lm-sub').textContent = cfg.sub; document.getElementById('ac-lm-pname').textContent = cfg.pname; document.getElementById('ac-lm-pval').innerHTML = cfg.pval + ' ₫ / tháng'; document.getElementById('ac-lm-buy-link').href = cfg.url; // Features document.getElementById('ac-lm-feats').innerHTML = cfg.feats.map(function(f){ return '
✓' + f + '
'; }).join(''); // Reset document.getElementById('ac-lm-key').value = ''; document.getElementById('ac-lm-key').className = 'ac-lm-input'; document.getElementById('ac-lm-status').textContent = ''; document.getElementById('ac-lm-status').className = ''; document.getElementById('ac-lm-devwarn').classList.remove('show'); document.getElementById('ac-lm-verify-btn').disabled = false; document.getElementById('ac-lm-verify-text').textContent = 'Xác nhận kích hoạt'; acLmTab('activate', null); document.getElementById('ac-lm-overlay').classList.add('show'); setTimeout(function(){ document.getElementById('ac-lm-key').focus(); }, 300); }; window.acLmClose = function() { document.getElementById('ac-lm-overlay').classList.remove('show'); acLmFeature = null; }; window.acLmTab = function(tab, btn) { document.querySelectorAll('.ac-lm-tab').forEach(function(b){ b.classList.remove('active'); }); document.querySelectorAll('.ac-lm-panel').forEach(function(p){ p.classList.remove('active'); }); document.getElementById('ac-lm-' + tab).classList.add('active'); if (btn) btn.classList.add('active'); else { var tabs = document.querySelectorAll('.ac-lm-tab'); if (tab === 'activate') tabs[0].classList.add('active'); else tabs[1].classList.add('active'); } }; window.acLmVerify = function() { var key = document.getElementById('ac-lm-key').value.trim().toUpperCase(); var statusEl = document.getElementById('ac-lm-status'); var verifyBtn = document.getElementById('ac-lm-verify-btn'); var verifyText = document.getElementById('ac-lm-verify-text'); var inputEl = document.getElementById('ac-lm-key'); if (!key || key.length < 4) { inputEl.classList.add('err'); statusEl.className = 'err'; statusEl.innerHTML = '⚠️ Vui lòng nhập mã kích hoạt.'; return; } var cfg = AC_LM_CONFIGS[acLmFeature]; if (!cfg) return; // Loading verifyBtn.disabled = true; verifyText.innerHTML = '
Đang xác nhận...'; statusEl.className = 'load'; statusEl.textContent = 'Đang kết nối server...'; inputEl.classList.remove('err','ok'); var deviceId = acGetDeviceId(); // ps2_bundle: thử verify ads_builder trước, nếu fail thử calendar var verifyFeature = cfg.lm_feature; if (cfg.lm_feature === 'ps2_bundle') verifyFeature = 'ads_builder'; var body = { license_key: key, feature: verifyFeature, device_id: deviceId }; if (acLmForceDevice) body.force_device = true; fetch(VERIFY_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) .then(function(r){ return r.json(); }) .then(function(data) { verifyBtn.disabled = false; verifyText.textContent = 'Xác nhận kích hoạt'; if (!data.valid && !data.device_conflict && cfg.lm_feature === 'ps2_bundle' && verifyFeature === 'ads_builder') { // Thử lại với calendar body.feature = 'calendar'; fetch(VERIFY_API, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(body) }) .then(function(r2){ return r2.json(); }) .then(function(d2) { verifyBtn.disabled = false; verifyText.textContent = 'Xác nhận kích hoạt'; if (d2.valid) { inputEl.classList.add('ok'); statusEl.className = 'ok'; statusEl.innerHTML = '✅ ' + (d2.message || 'Kích hoạt thành công!'); var expiry = Date.now() + 30*24*60*60*1000; localStorage.setItem(cfg.storage, JSON.stringify({ expiry: expiry, key: key })); if (cfg.storage === 'ps2_premium') { isPremium = true; } setTimeout(function(){ acLmClose(); location.reload(); }, 1200); } else { inputEl.classList.add('err'); statusEl.className = 'err'; statusEl.innerHTML = '❌ ' + (d2.message || 'Mã không hợp lệ.'); } }).catch(function(){ statusEl.className='err'; statusEl.innerHTML='❌ Lỗi kết nối.'; }); return; } if (data.valid) { // ✅ Thành công inputEl.classList.add('ok'); statusEl.className = 'ok'; statusEl.innerHTML = '✅ ' + (data.message || 'Kích hoạt thành công!'); var expiry = Date.now() + 30 * 24 * 60 * 60 * 1000; localStorage.setItem(cfg.storage, JSON.stringify({ expiry: expiry, key: key })); if (cfg.storage === 'ps2_premium') { isPremium = true; // Show premium content ngay không cần reload var psPaywall = document.getElementById('ps-paywall'); var psPremium = document.getElementById('ps-premium-content'); if (psPaywall) psPaywall.style.display = 'none'; if (psPremium) psPremium.style.display = 'block'; } setTimeout(function(){ acLmClose(); location.reload(); }, 1200); } else if (data.device_conflict) { // ⚠️ Đang dùng thiết bị khác inputEl.classList.add('err'); statusEl.className = 'err'; statusEl.innerHTML = '⚠️ Mã đang dùng trên thiết bị khác.'; document.getElementById('ac-lm-devwarn').classList.add('show'); verifyText.textContent = 'Xác nhận chuyển thiết bị'; acLmForceDevice = true; } else { // ❌ Không hợp lệ inputEl.classList.add('err'); statusEl.className = 'err'; statusEl.innerHTML = '❌ ' + (data.message || 'Mã không hợp lệ. Kiểm tra lại email.'); acLmForceDevice = false; document.getElementById('ac-lm-devwarn').classList.remove('show'); } }) .catch(function(err) { verifyBtn.disabled = false; verifyText.textContent = 'Xác nhận kích hoạt'; statusEl.className = 'err'; statusEl.innerHTML = '❌ Lỗi kết nối. Vui lòng thử lại.'; }); }; // ── Override ps2Upgrade + swUpgrade + ps2ShowPaywall ── window.ps2Upgrade = function() { acLmOpen('ads_builder'); }; window.ps2ShowPaywall = function() { acLmOpen('ads_builder'); }; window.swUpgrade = function() { acLmOpen('seo_writer'); }; // Calendar paywall nếu cần window.calUpgrade = function() { acLmOpen('calendar'); }; /* ══ CALENDAR MONTH PICKER JS ══ */ (function() { var MONTHS = ['Th.1','Th.2','Th.3','Th.4','Th.5','Th.6','Th.7','Th.8','Th.9','Th.10','Th.11','Th.12']; var selectedMonth = 6; var selectedYear = 2026; function calMpRender() { var grid = document.getElementById('cal-mp-grid'); var yearEl = document.getElementById('cal-mp-year'); if (!grid || !yearEl) return; yearEl.textContent = selectedYear; var now = new Date(); var curM = now.getMonth() + 1; var curY = now.getFullYear(); grid.innerHTML = MONTHS.map(function(name, i) { var m = i + 1; var cls = 'cal-mp-month'; if (m === selectedMonth && selectedYear === selectedYear) cls += ' active'; if (m === curM && selectedYear === curY) cls += ' current'; return ''; }).join(''); } window.calMpToggle = function() { var popup = document.getElementById('cal-mp-popup'); if (!popup) return; popup.classList.toggle('show'); if (popup.classList.contains('show')) calMpRender(); }; window.calMpYear = function(dir) { selectedYear += dir; calMpRender(); }; window.calMpSelect = function(m) { selectedMonth = m; document.getElementById('cal-month').value = m + '/' + selectedYear; document.getElementById('cal-mp-display').textContent = 'Tháng ' + m + ' / ' + selectedYear; document.getElementById('cal-mp-popup').classList.remove('show'); calMpRender(); }; // Đóng popup khi click ngoài — chỉ xử lý khi popup đang show document.addEventListener('click', function(e) { try { var popup = document.getElementById('cal-mp-popup'); var input = document.getElementById('cal-mp-input'); if (!popup || !input) return; if (!popup.classList.contains('show')) return; if (!popup.contains(e.target) && !input.contains(e.target)) { popup.classList.remove('show'); } } catch(err) { /* ignore */ } }, { passive: true }); // Init render setTimeout(calMpRender, 300); })(); /* ══ EXPORT EXCEL + RESET ══ */ // Parse lịch content text → array of rows function calParseRows(text) { var rows = []; var lines = text.split('\n'); var headers = ['Ngày','Format','Loại Content','Chủ đề','Caption gợi ý','Giờ đăng']; rows.push(headers); lines.forEach(function(line) { line = line.trim(); if (!line.startsWith('|')) return; var cols = line.split('|').map(function(c){ return c.trim(); }).filter(function(c,i){ return i > 0 && c !== ''; }); if (cols.length >= 2 && !/^[-|]+$/.test(cols[0])) { // Loại bỏ dòng separator (---|---|...) if (!cols[0] || cols[0].trim().replace(/-/g,'').trim() === '') return; // Pad đủ 6 cột while (cols.length < 6) cols.push(''); rows.push(cols.slice(0,6)); } }); return rows; } // Tạo file Excel đơn giản dạng CSV (UTF-8 BOM để Excel đọc được tiếng Việt) window.calExportExcel = function() { var text = document.getElementById('cal-output-text').textContent; if (!text || text.length < 10) { alert('Chưa có lịch content để xuất!'); return; } var rows = calParseRows(text); if (rows.length <= 1) { // Fallback: export toàn bộ text dạng txt var blob = new Blob(['\uFEFF' + text], { type: 'text/plain;charset=utf-8' }); var a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'lich-content-adscoffee.txt'; a.click(); return; } // Build CSV var csv = rows.map(function(row) { return row.map(function(cell) { // Escape double quotes cell = (cell || '').replace(/"/g, '""'); // Wrap in quotes nếu có dấu phẩy hoặc xuống dòng if (cell.includes(',') || cell.includes('\n') || cell.includes('"')) { cell = '"' + cell + '"'; } return cell; }).join(','); }).join('\n'); // UTF-8 BOM để Excel nhận diện tiếng Việt var blob = new Blob(['\uFEFF' + csv], { type: 'text/csv;charset=utf-8' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'lich-content-adscoffee.csv'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }; window.calReset = function() { if (!confirm('Xóa lịch content hiện tại?')) return; document.getElementById('cal-output-text').textContent = ''; document.getElementById('cal-output').style.display = 'none'; // Reset form var fields = ['cal-brand','cal-event']; fields.forEach(function(id){ var el = document.getElementById(id); if (el) el.value = ''; }); // Reset month picker document.getElementById('cal-mp-display').textContent = 'Tháng 6 / 2026'; document.getElementById('cal-month').value = '6/2026'; // Reset btn text var btn = document.getElementById('cal-btn-text'); if (btn) btn.textContent = '📅 Tạo Lịch Content 30 ngày'; document.getElementById('cal-btn').disabled = false; }; window.abExportExcel = function() { var text = document.getElementById('ab-output-text').textContent; if (!text || text.length < 10) { alert('Chưa có campaign để xuất!'); return; } var blob = new Blob(['\uFEFF' + text], { type: 'text/plain;charset=utf-8' }); var a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'campaign-adscoffee.txt'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(a.href); }; window.abReset = function() { if (!confirm('Xóa campaign hiện tại?')) return; document.getElementById('ab-output-text').textContent = ''; document.getElementById('ab-output').style.display = 'none'; // Reset form var fields = ['ab-name','ab-price','ab-area','ab-usp','ab-pain','ab-goal','ab-cta']; fields.forEach(function(id){ var el = document.getElementById(id); if (el) el.value = ''; }); var btn = document.getElementById('ab-btn-text'); if (btn) btn.textContent = '⭐ Tạo Campaign với AI'; document.getElementById('ab-btn').disabled = false; }; /* ══ SAFETY NET — Đảm bảo tab functions luôn available ══ */ (function() { function ensureTabFunctions() { // Nếu ps2Tab chưa được define (JS chưa load xong), bind lại if (typeof window.ps2Tab !== 'function') { console.warn('ps2Tab not ready, using fallback'); window.ps2Tab = function(id, btn) { document.querySelectorAll('#ps2 .ps-panel').forEach(function(p){ p.classList.remove('active'); }); document.querySelectorAll('#ps2 .ps-tab').forEach(function(b){ b.classList.remove('active'); }); var panel = document.getElementById('panel-' + id); if (panel) panel.classList.add('active'); if (btn) btn.classList.add('active'); }; } } // Dùng event delegation cho toàn bộ tab bar document.addEventListener('click', function(e) { var tab = e.target.closest('#ps2 .ps-tab'); if (!tab) return; var tabId = tab.getAttribute('data-tab'); if (!tabId) return; e.preventDefault(); ensureTabFunctions(); window.ps2Tab(tabId, tab); }, true); // useCapture=true để chạy trước mọi handler khác }, false); /* ══ END SAFETY NET ══ */