Site Builder
Editing:
tools-writing-social.php
writable 0666
<?php /***************************************************************** * Promptinator — Multichannel Repurposer v1.2 * ------------------------------------------------------------- * • Shared login toolbar * • Persona “Emotion / voice” + “Personal impact” inputs *****************************************************************/ require_once $_SERVER['DOCUMENT_ROOT'].'/openai/init.php'; ai_handle_key_post(); /* ---------- AJAX ------------------------------------------------ */ if ($_SERVER['REQUEST_METHOD']==='POST' && ($_GET['ajax']??'')==='1') { header('Content-Type: application/json; charset=utf-8'); if (!ai_has_key()) { echo json_encode(['error'=>'No API key']); exit; } $prompt = trim($_POST['prompt']??''); $model = trim($_POST['model'] ?? 'gpt-3.5-turbo'); if(!$prompt){ echo json_encode(['error'=>'Prompt empty']); exit; } $html = ai_chat($prompt,['model'=>$model,'max_tokens'=>1200,'temperature'=>0.7]); echo $html ? json_encode(['html'=>$html]) : json_encode(['error'=>'Empty response']); exit; } /* ---------- page ------------------------------------------------ */ $models = ['gpt-3.5-turbo','gpt-4o-mini','gpt-4']; ?> <!doctype html> <html lang="en"><head> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <title>Multichannel Repurposer • Promptinator</title> <style> :root{--bg:#f1f4fb;--card:#fff;--brand:#004cff;--brand-d:#0841c4;--dark:#121720; --green:#5af287;--red:#e24d4b;--radius:26px;--shadow:0 6px 30px rgba(0,0,0,.08); font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:16px} body{margin:0;min-height:100vh;background:var(--bg);display:flex;flex-direction:column} .breadcrumb{background:#ececec;padding:.7rem 1.2rem;font-weight:600} .breadcrumb a{color:var(--brand);text-decoration:none} main{max-width:1000px;width:100%;margin:2.4rem auto;padding:0 1.2rem;flex:1} .tool{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);padding:2rem;display:grid;gap:1.6rem} label{font-weight:600;font-size:.95rem;display:block;margin-bottom:.3rem} input,select,textarea{width:100%;padding:.75rem 1rem;border:1px solid #d0d6e7;border-radius:10px;font-size:1rem} textarea{min-height:90px;resize:vertical;font-family:ui-monospace,monospace} input:focus,select:focus,textarea:focus{outline:none;border-color:var(--brand)} .btn{background:var(--brand);color:#fff;border:none;border-radius:10px;padding:.9rem 1.7rem;font-size:1rem;font-weight:600;cursor:pointer} .btn:hover{background:var(--brand-d)} small{font-size:.8rem;color:#555} .grid{display:grid;gap:1.3rem} @media(min-width:760px){.grid.two{grid-template-columns:1fr 1fr}} #spin{display:none;gap:.5ch;align-items:center;margin-top:.9rem} #spin.show{display:flex} #spin svg{width:20px;height:20px;animation:rot 1s linear infinite}@keyframes rot{to{transform:rotate(360deg)}} .preview{border:1px solid #d0d4e0;padding:1rem;border-radius:12px;background:#fafbff;max-height:60vh;overflow:auto} .micBtn{position:absolute;right:.7rem;top:50%;transform:translateY(-50%);border:none;background:none;font-size:1.2rem;cursor:pointer} .inline-row{display:flex;align-items:center;gap:.55rem;margin:.4rem 0} .inline-row input[type=checkbox]{inline-size:18px;block-size:18px;margin:0} </style> </head><body> <nav class="breadcrumb"> <a href="/members/dashboard.php">Dashboard</a> » <a href="/ai-tools/tools.php">AI Toolbox</a> » Multichannel Repurposer <a href="/<?= htmlspecialchars($_SESSION['slug']??'') ?>/" style="float:right">View Site</a> </nav> <?php ai_render_key_bar(); ?> <?php require_once $_SERVER['DOCUMENT_ROOT'].'/ai-tools/share.php'; ?> <main> <?php if(!ai_has_key()): ?> <div class="tool" style="text-align:center"> <h2>Connect your OpenAI key</h2> <p>Save the key in the black bar above to unlock the Repurposer.</p> </div> <?php else: ?> <div class="tool"> <h2>Create personalised cross‑channel content</h2> <form id="gen"> <input type="hidden" name="prompt" id="promptField"> <input type="hidden" name="model" id="modelHidden" value="gpt-3.5-turbo"> <!-- source --------------------------------------------------> <label>Source (text or URL) <div style="position:relative"> <textarea id="source" placeholder="Paste URL or text…"></textarea> <button type="button" class="micBtn" id="micSrc" title="Dictate">🎤</button> </div> </label> <!-- persona emotion / impact -------------------------------> <label>Emotion / persona voice <div style="position:relative"> <textarea id="emotion" rows="2" placeholder="e.g. Excited, hopeful…"></textarea> <button type="button" class="micBtn" id="micEmo" title="Dictate emotion">🎤</button> </div> </label> <label>Personal impact <small>(optional)</small> <div style="position:relative"> <textarea id="impact" rows="2" placeholder="Why this matters to you…"></textarea> <button type="button" class="micBtn" id="micImp" title="Dictate impact">🎤</button> </div> </label> <!-- channels -----------------------------------------------> <label>Channels</label> <select id="channels" multiple size="6" style="min-height:170px"> <option value="Twitter">Twitter / X</option> <option value="LinkedIn">LinkedIn</option> <option value="Facebook">Facebook</option> <option value="Instagram">Instagram caption</option> <option value="Email">Email intro</option> <option value="Blog">Blog excerpt</option> </select> <!-- tone / style ------------------------------------------> <div class="grid two"> <label>Tone <select id="tone"><?php foreach(['Neutral','Cheerful','Professional','Inspirational','Assertive','Witty'] as $t) echo "<option>$t</option>"; ?></select> </label> <label>Style <select id="style"><?php foreach(['Informative','Persuasive','Storytelling','Analytical'] as $s) echo "<option>$s</option>"; ?></select> </label> </div> <!-- extras -------------------------------------------------> <label>Call‑to‑action <small>(optional)</small> <input id="cta" placeholder="e.g. Visit our store today"> </label> <label>Brand hashtags / keywords <input id="tags" placeholder="#BestDealOn"> </label> <!-- preview + buttons --------------------------------------> <label>Prompt preview <textarea id="promptBox" readonly></textarea> </label> <button type="button" id="copyP" class="btn copyBtn" hidden>Copy Prompt</button> <button id="go" class="btn">Generate</button> <div id="spin"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"/></svg><span id="s">0</span> s</div> </form> <section id="out" style="display:none"> <h3>HTML source</h3> <textarea id="raw" readonly style="min-height:170px"></textarea> <button class="btn copyBtn" id="copyRaw">Copy HTML</button> <h3 style="margin-top:1.4rem">Rendered preview</h3> <div id="rend" class="preview"></div> <button class="btn copyBtn" id="copyR">Copy Rendered</button> </section> </div> <?php endif; ?> </main> <script> (()=>{ const $=id=>document.getElementById(id); /* ---------- microphones ------------------------------------ */ function bindMic(btnID, targetID){ const BTN=$(btnID), T=$(targetID); if(!BTN || !T) return; if(!(window.SpeechRecognition||window.webkitSpeechRecognition)){ BTN.style.display='none'; return; } const SR=new (window.SpeechRecognition||window.webkitSpeechRecognition)(); SR.lang='en-US'; BTN.onclick=()=>{ try{SR.start();}catch{} }; SR.onresult=e=>{ T.value=e.results[0][0].transcript; buildPrompt(); }; } bindMic('micSrc','source'); bindMic('micEmo','emotion'); bindMic('micImp','impact'); /* ---------- prompt builder --------------------------------- */ ['source','emotion','impact','channels','tone','style','cta','tags'] .forEach(id=>$(id).addEventListener(id==='channels'?'change':'input',buildPrompt)); buildPrompt(); function buildPrompt(){ const src=$('source').value.trim(), emo=$('emotion').value.trim(), imp=$('impact').value.trim(), chans=[...$('channels').selectedOptions].map(o=>o.value); if(!src||!chans.length){ $('promptBox').value=''; $('promptField').value=''; $('copyP').hidden=true; return; } const tone=$('tone').value, style=$('style').value, cta=$('cta').value.trim(), tags=$('tags').value.trim(); const chanList=chans.map(c=>'• '+c).join('\n'); let p=`You are a senior social‑media copy‑writer.\nCHANNELS TO CREATE:\n${chanList}\nTONE: ${tone}\nSTYLE: ${style}.`; if(emo) p+=`\nEMOTION / VOICE: ${emo}.`; if(imp) p+=`\nPERSONAL IMPACT: ${imp}.`; if(cta) p+=`\nCall‑to‑action: "${cta}".`; if(tags) p+=`\nIncorporate hashtags/keywords: ${tags}.`; p+=`\n\nSOURCE:\n${src}\n\nReturn ONLY valid HTML with <h2>Channel</h2> followed by the content.`; $('promptBox').value = p; $('promptField').value = p; $('copyP').hidden = false; } $('copyP').onclick=()=>navigator.clipboard.writeText($('promptBox').value).then(()=>flash($('copyP'))); /* ---------- model selector sync ---------------------------- */ if($('modelSel')) $('modelSel').onchange=e=>$('modelHidden').value=e.target.value; /* ---------- AJAX ------------------------------------------ */ $('gen').onsubmit=e=>{ e.preventDefault(); buildPrompt(); if(!$('promptField').value){ alert('Fill required fields'); return; } $('go').disabled=true; $('spin').classList.add('show'); let s=0; $('s').textContent='0'; const t=setInterval(()=>$('s').textContent=++s,1000); fetch('?ajax=1',{method:'POST',body:new FormData($('gen'))}) .then(r=>r.json()).then(j=>{ clearInterval(t); $('spin').classList.remove('show'); $('go').disabled=false; if(j.error){ alert(j.error); return; } $('raw').value=j.html; $('rend').innerHTML=j.html; $('out').style.display=''; $('copyRaw').onclick=()=>navigator.clipboard.writeText($('raw').value).then(()=>flash($('copyRaw'))); $('copyR').onclick =()=>navigator.clipboard.writeText($('rend').innerHTML).then(()=>flash($('copyR'))); $('rend').scrollIntoView({behavior:'smooth'}); }) .catch(err=>{ clearInterval(t); $('spin').classList.remove('show'); $('go').disabled=false; alert(err); }); }; /* ---------- flash helper ----------------------------------- */ function flash(btn){const t=btn.textContent;btn.textContent='✔ Copied';setTimeout(()=>btn.textContent=t,1200);} })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel