Site Builder
Editing:
cta.php
writable 0666
<?php /************************************************************************** * CTA EDITOR – Admin panel for call‑to‑action cards * ---------------------------------------------------------------------- * JSON schema (cta.json) * [ * { "title":"⚡ Join…", "html":"<p>…</p>", * "button": {"label":"Subscribe","url":"https://…"} } * ] * Works for ?user=slug → /social/<slug>/cta.json * ?ph=######## → /ph/<phone>/cta.json * © 2025 BestDealOn – PHP 8.1+ *************************************************************************/ require_once __DIR__.'/../lib/auth.php'; require_login(); /* ---------- 1. Resolve target directory ---------- */ $root = $_SERVER['DOCUMENT_ROOT']; $slug = preg_replace('/[^a-z0-9_]/i','', $_GET['user'] ?? ''); $ph = preg_replace('/\D/','', $_GET['ph'] ?? ''); if ($slug) { $dir = "$root/social/$slug"; $file = "$dir/cta.json"; $label= '@'.$slug; $page = "https://bestdealon.com/social/$slug/"; } elseif ($ph && strlen($ph)===10) { $dir = "$root/ph/$ph"; $file = "$dir/cta.json"; $label= $ph; $page = "https://bestdealon.com/$ph/"; } else lookup(); $safePage = htmlspecialchars($page, ENT_QUOTES,'UTF-8'); if (!is_dir($dir)) lookup('Profile not found.'); /* ---------- 2. Lookup helper ---------- */ function lookup(string $err=''){?> <!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <title>Edit CTA | BestDealOn</title> <style> body{background:#f6f8fb;font-family:system-ui,Arial,sans-serif;margin:0;color:#234} .wrap{max-width:480px;margin:3em auto;background:#fff;padding:2em;border-radius:18px; box-shadow:0 2px 18px #dde3fa50;text-align:center} input{width:100%;padding:.7em;border:1.4px solid #b7c2df;border-radius:7px;font-size:1.05em} button{margin-top:1em;padding:.7em 1.6em;font-size:1.05em;font-weight:700;background:#2357d7; color:#fff;border:none;border-radius:8px;cursor:pointer} .err{color:#c62828;margin-bottom:.8em} </style></head><body> <div class="wrap"> <h1>Look up Your CTA</h1> <?php if($err) echo "<div class='err'>$err</div>"; ?> <form method="get" style="display:flex;flex-direction:column;gap:.8rem"> <input type="text" name="user" placeholder="@username"> <div>— or —</div> <input type="tel" name="ph" placeholder="10‑digit phone"> <button type="submit">Load CTA</button> </form> </div></body></html><?php exit; } /* ---------- 3. POST save ---------- */ if ($_SERVER['REQUEST_METHOD']==='POST'){ $json = file_get_contents('php://input'); if (!is_dir($dir)) mkdir($dir,0777,true); file_put_contents($file,$json,LOCK_EX); echo '{"success":true}'; exit; } /* ---------- 4. Load existing ---------- */ $ctas = is_file($file) ? json_decode(file_get_contents($file),true,512,JSON_THROW_ON_ERROR):[]; if(!is_array($ctas)) $ctas=[]; /* ---------- 5. Page HTML ---------- */ ?><!doctype html><html lang="en"><head> <meta charset="utf-8"><title>Edit CTA – <?= htmlspecialchars($label) ?></title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" referrerpolicy="no-referrer"> <style> :root{ --bg:#f5f8fb;--fg:#234;--card:#fffbe6;--card-brd:#ffd973; --accent:#2357d7;--accent-dk:#1347c0;--warn:#c9302c; } body{margin:0;font-family:system-ui,Arial,sans-serif;background:var(--bg);color:var(--fg)} a{color:var(--accent);text-decoration:none} .top{background:#eee;padding:.8em 1.2em;font-weight:900} .container{max-width:860px;margin:2.4rem auto;padding:0 1rem} #list{list-style:none;margin:0;padding:0} .item{background:var(--card);border:2px solid var(--card-brd);border-radius:18px; box-shadow:0 3px 20px #f5db9c55;padding:1.3rem 1.2rem;margin-bottom:1.4rem; display:flex;flex-direction:column;gap:.7rem} .item.dragging{opacity:.55} .item input,.item textarea{ width:100%;padding:.55rem;border:1px solid #b7c2df;border-radius:8px;font-size:1.04rem} .item textarea{resize:vertical;min-height:120px;font-family:inherit} .item .row-btns{display:flex;gap:.65rem;margin-top:.3rem} .move,.del{padding:.45rem .75rem;border-radius:8px;font-weight:700;border:none;cursor:pointer} .move{background:#aac8ff;color:#103e9d} .move:hover{background:#90b4ff} .del {background:#ffd5d5;color:var(--warn)} .del:hover{background:#ffcbcb} #addBtn{background:var(--accent);color:#fff;font-size:1.03rem;padding:.6rem 1.2rem;margin-top:.4rem} #addBtn:hover{background:var(--accent-dk)} #saveBtn{background:#ef8f13;color:#fff;font-size:1.08rem;padding:.68rem 2rem} #msg{font-weight:700;margin-top:1rem} </style></head><body> <a href="<?= $safePage ?>" style="float:right;margin:.6rem 1rem 0 0;">View Page</a> <div class="top"><a href="/">BestDealOn</a> » <a href="/members/dashboard.php">Dashboard</a> » CTA Editor</div> <div class="container"> <h1><i class="fa-solid fa-bullhorn"></i> CTA for <?= htmlspecialchars($label) ?></h1> <ul id="list"></ul> <button id="addBtn"><i class="fa-solid fa-plus"></i> Add CTA</button> <div style="margin-top:2rem;text-align:right"><button id="saveBtn"><i class="fa-solid fa-floppy-disk"></i> Save All</button></div> <div id="msg"></div> </div> <script> const ctas = <?= json_encode($ctas, JSON_UNESCAPED_SLASHES) ?>; const list = document.getElementById('list'); function esc(s){return String(s).replace(/[&<>"']/g,m=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));} function makeItem(o={title:'',html:'<p></p>',button:{label:'',url:''}}){ const li=document.createElement('li');li.className='item';li.draggable=true; li.innerHTML=` <input class="title" placeholder="CTA title" value="${esc(o.title)}"> <textarea class="html" rows="4" placeholder="HTML body (basic tags)">${esc(o.html)}</textarea> <input class="blabel" placeholder="Button label" value="${esc(o.button?.label||'')}"> <input class="burl" placeholder="https://example.com" value="${esc(o.button?.url||'')}"> <div class="row-btns"> <button class="move up">↑</button> <button class="move down">↓</button> <button class="del">✖</button> </div>`; return li; } if(ctas.length) ctas.forEach(c=>list.appendChild(makeItem(c))); else list.appendChild(makeItem()); /* drag reorder */ let dragEl;list.addEventListener('dragstart',e=>{dragEl=e.target;dragEl.classList.add('dragging');}); list.addEventListener('dragend', e=>{dragEl.classList.remove('dragging');dragEl=null;}); list.addEventListener('dragover', e=>{e.preventDefault();const after=[...list.querySelectorAll('.item:not(.dragging)')].find(li=>e.clientY<li.getBoundingClientRect().top+li.offsetHeight/2);list.insertBefore(dragEl,after||null);}); /* row buttons */ document.getElementById('addBtn').onclick=()=>list.appendChild(makeItem()); list.addEventListener('click',e=>{const li=e.target.closest('.item');if(!li)return;if(e.target.classList.contains('del'))li.remove();if(e.target.classList.contains('up'))li.previousElementSibling&&list.insertBefore(li,li.previousElementSibling);if(e.target.classList.contains('down'))li.nextElementSibling&&list.insertBefore(li.nextElementSibling,li);}); /* save */ document.getElementById('saveBtn').onclick=async()=>{ const arr=[...list.children].map(li=>({ title :li.querySelector('.title').value.trim(), html :li.querySelector('.html').value.trim(), button:{label:li.querySelector('.blabel').value.trim(),url:li.querySelector('.burl').value.trim()} })).filter(x=>x.title&&x.button.label&&x.button.url); const r=await fetch(location.href,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(arr)}); const m=document.getElementById('msg');m.textContent=r.ok?'✅ Saved':'❌ Error';m.style.color=r.ok?'green':'#c62828';setTimeout(()=>m.textContent='',2000); }; </script> </body></html>
Save changes
Create folder
writable 0777
Create
Cancel