{"id":734,"date":"2025-09-26T18:35:04","date_gmt":"2025-09-26T21:35:04","guid":{"rendered":"https:\/\/luplo.net\/?page_id=734"},"modified":"2025-10-02T09:12:56","modified_gmt":"2025-10-02T12:12:56","slug":"chatgpt","status":"publish","type":"page","link":"https:\/\/luplo.net\/index.php\/chatgpt\/","title":{"rendered":"ChatGPT"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"734\" class=\"elementor elementor-734\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-34d13e8 e-flex e-con-boxed e-con e-parent\" data-id=\"34d13e8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-02a0759 elementor-widget elementor-widget-shortcode\" data-id=\"02a0759\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <style>\n    .firmorama-quiz { max-width:820px; margin:18px auto; font-family:system-ui, -apple-system, \"Segoe UI\", Roboto, Arial; border:1px solid #e6e6e6; border-radius:8px; overflow:hidden; background:#fff; }\n    .firmorama-quiz .chat { padding:14px; height:460px; overflow:auto; background:#fbfcfe; }\n    .firmorama-quiz .msg { margin:10px 0; padding:12px; border-radius:10px; display:block; max-width:86%; word-wrap:break-word; }\n    .firmorama-quiz .assistant { background:#e9f6ff; color:#052a3a; }\n    .firmorama-quiz .assistant .meta { font-size:13px; color:#4b6b7a; margin-top:6px; }\n    .firmorama-quiz .user { background:#eaffea; color:#0a3a0a; margin-left:auto; text-align:right; }\n    .firmorama-quiz .controls { display:flex; gap:8px; padding:12px; border-top:1px solid #eee; background:#fff; align-items:center; }\n    .firmorama-quiz input[type=\"text\"] { flex:1; padding:11px 12px; font-size:15px; border:1px solid #ddd; border-radius:6px; }\n    .firmorama-quiz button { padding:9px 12px; font-size:14px; cursor:pointer; border-radius:6px; border:1px solid #ddd; background:#fff; }\n    .firmorama-quiz .start-btn { background:#0b6cff; color:#fff; border-color:#0b6cff; }\n    .firmorama-quiz .small { font-size:13px; color:#777; }\n    .firmorama-quiz .error { color:#b00; background:#ffecec; padding:10px; border-radius:6px; }\n    .firmorama-quiz .final-report { white-space:pre-wrap; background:#fffdfa; padding:12px; border-radius:6px; border:1px solid #f0e6c8; }\n    .firmorama-quiz .meta-badge { font-size:12px; color:#666; margin-left:8px; }\n    <\/style>\n\n    <div class=\"firmorama-quiz\" id=\"firmorama-quiz\">\n        <div class=\"chat\" id=\"firmorama-chat\" aria-live=\"polite\">\n            <div class=\"msg assistant\" id=\"firmorama-welcome\">\n                <strong>Firmorama \u2014 Diagn\u00f3stico de Branding<\/strong>\n                <div class=\"meta\">Pressione <em>Enter<\/em> no campo abaixo ou clique em <strong>Iniciar diagn\u00f3stico<\/strong> para come\u00e7ar.<\/div>\n                <div class=\"small\">O diagn\u00f3stico ser\u00e1 conduzido com perguntas uma-a-uma e coment\u00e1rios curtos entre cada pergunta. Ao final, ser\u00e1 gerado um relat\u00f3rio estruturado.<\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"controls\" role=\"form\" aria-label=\"Quiz controls\">\n            <form id=\"firmorama-form\" style=\"display:flex; width:100%;\" onsubmit=\"return false;\">\n                <input id=\"firmorama-input\" type=\"text\" autocomplete=\"off\" placeholder=\"Pressione Enter para iniciar...\" \/>\n                <button id=\"firmorama-start\" class=\"start-btn\">Iniciar diagn\u00f3stico<\/button>\n                <button id=\"firmorama-send\" style=\"display:none;\">Enviar<\/button>\n                <button id=\"firmorama-restart\" type=\"button\" style=\"display:none;background:#f4f4f4;\">Recome\u00e7ar<\/button>\n            <\/form>\n        <\/div>\n    <\/div>\n\n    <script>\n    (function(){\n        const ajaxurl = \"https:\/\/luplo.net\/wp-admin\/admin-ajax.php\";\n        const chatEl = document.getElementById('firmorama-chat');\n        const input = document.getElementById('firmorama-input');\n        const startBtn = document.getElementById('firmorama-start');\n        const sendBtn = document.getElementById('firmorama-send');\n        const restartBtn = document.getElementById('firmorama-restart');\n        const qcount = 7;\n\n        \/\/ keep history in-browser (array of {role,content})\n        let history = []; \/\/ will contain user+assistant turns as objects\n        let answersCount = 0;\n        let awaiting = false;\n        let finished = false;\n\n        function appendAssistant(html) {\n            const d = document.createElement('div');\n            d.className = 'msg assistant';\n            d.innerHTML = html;\n            chatEl.appendChild(d);\n            chatEl.scrollTop = chatEl.scrollHeight;\n        }\n        function appendUser(text) {\n            const d = document.createElement('div');\n            d.className = 'msg user';\n            d.innerText = text;\n            chatEl.appendChild(d);\n            chatEl.scrollTop = chatEl.scrollHeight;\n        }\n        function appendError(text) {\n            const d = document.createElement('div');\n            d.className = 'msg assistant error';\n            d.innerHTML = '<strong>Erro:<\/strong> ' + text;\n            chatEl.appendChild(d);\n            chatEl.scrollTop = chatEl.scrollHeight;\n        }\n\n        function setPlaceholder(t) { input.placeholder = t; }\n\n        async function serverCall(actionType, message) {\n            \/\/ send history + message + action_type\n            const payload = new URLSearchParams();\n            payload.append('action','firmorama_chat_with_prompt');\n            payload.append('action_type', actionType);\n            payload.append('message', message || '');\n            payload.append('history', JSON.stringify(history));\n\n            const res = await fetch(ajaxurl, {\n                method: 'POST',\n                headers: {'Content-Type':'application\/x-www-form-urlencoded'},\n                body: payload\n            });\n            return res.json();\n        }\n\n        async function startFlow() {\n            if (awaiting) return;\n            awaiting = true;\n            setPlaceholder('Iniciando...');\n            startBtn.disabled = true;\n            const res = await serverCall('start', '');\n            startBtn.disabled = false;\n            awaiting = false;\n            if(res.error) {\n                appendError(res.error);\n                setPlaceholder('Pressione Enter ou clique em Iniciar para tentar novamente.');\n                return;\n            }\n            handleAssistantResponse(res);\n            sendBtn.style.display = 'inline-block';\n            startBtn.style.display = 'none';\n            restartBtn.style.display = 'inline-block';\n            setPlaceholder('Digite sua resposta...');\n        }\n\n        async function sendAnswer(text) {\n            if (awaiting || finished) return;\n            if (!text || text.trim() === '') return;\n            appendUser(text);\n            \/\/ push user message to history (client-side)\n            history.push({role:'user', content:text});\n            answersCount++;\n            setPlaceholder('Aguarde...');\n            awaiting = true;\n            const res = await serverCall('reply', text);\n            awaiting = false;\n            if(res.error) {\n                appendError(res.error);\n                setPlaceholder('Digite sua resposta...');\n                return;\n            }\n            handleAssistantResponse(res);\n            setPlaceholder('Digite sua resposta...');\n        }\n\n        function handleAssistantResponse(res) {\n            \/\/ res can be structured: { type:'question', comment, question } or {type:'final', report} or raw\n            if(res.type === 'question') {\n                \/\/ assistant returned JSON-structured question\n                if(res.comment) {\n                    appendAssistant('<div>' + escapeHtml(res.comment) + '<\/div>');\n                    history.push({role:'assistant', content:res.comment});\n                }\n                if(res.question) {\n                    appendAssistant('<div><strong>' + escapeHtml(res.question) + '<\/strong><\/div>');\n                    \/\/ store assistant question in history too\n                    history.push({role:'assistant', content:res.question});\n                }\n                \/\/ continue\n            } else if(res.type === 'final') {\n                appendAssistant('<div class=\"final-report\">' + res.report + '<\/div>');\n                history.push({role:'assistant', content:res.report});\n                finished = true;\n                setPlaceholder('Diagn\u00f3stico finalizado.');\n            } else if(res.type === 'raw') {\n                appendAssistant('<div>' + res.raw + '<\/div>');\n                history.push({role:'assistant', content:res.raw});\n            } else if(res.type === 'error') {\n                appendError(res.error || 'Erro desconhecido do assistente.');\n            } else {\n                \/\/ fallback\n                if(res.raw) appendAssistant('<div>' + res.raw + '<\/div>');\n                else appendAssistant('<div>' + (res.reply || 'Sem resposta') + '<\/div>');\n            }\n            chatEl.scrollTop = chatEl.scrollHeight;\n        }\n\n        \/\/ helpers\n        function escapeHtml(text) {\n            if(!text) return '';\n            return text\n                .replace(\/&\/g, \"&amp;\")\n                .replace(\/<\/g, \"&lt;\")\n                .replace(\/>\/g, \"&gt;\");\n        }\n\n        \/\/ events\n        startBtn.addEventListener('click', function(e){ e.preventDefault(); startFlow(); });\n        restartBtn.addEventListener('click', async function(e){\n            e.preventDefault();\n            \/\/ reset client-side\n            history = [];\n            answersCount = 0;\n            finished = false;\n            chatEl.innerHTML = '';\n            const welcome = document.createElement('div');\n            welcome.className = 'msg assistant';\n            welcome.id = 'firmorama-welcome';\n            welcome.innerHTML = '<strong>Firmorama \u2014 Diagn\u00f3stico de Branding<\/strong><div class=\"meta\">Pressione <em>Enter<\/em> no campo abaixo ou clique em <strong>Iniciar diagn\u00f3stico<\/strong> para come\u00e7ar.<\/div><div class=\"small\">O diagn\u00f3stico ser\u00e1 conduzido com perguntas uma-a-uma.<\/div>';\n            chatEl.appendChild(welcome);\n            setPlaceholder('Pressione Enter para iniciar...');\n            startBtn.style.display = 'inline-block';\n            sendBtn.style.display = 'none';\n            restartBtn.style.display = 'none';\n            startBtn.disabled = false;\n        });\n\n        \/\/ Enter key behavior\n        input.addEventListener('keydown', function(e){\n            if (e.key === 'Enter' && !e.shiftKey) {\n                e.preventDefault();\n                \/\/ If not started yet -> start when field empty or always allow start\n                if (startBtn.style.display !== 'none' && (input.value.trim() === '')) {\n                    startFlow();\n                    return;\n                }\n                if (input.value.trim() !== '') {\n                    sendAnswer(input.value.trim());\n                    input.value = '';\n                }\n            }\n        });\n\n        \/\/ also provide click 'Enviar' support (hidden send button)\n        sendBtn.addEventListener('click', function(e){\n            e.preventDefault();\n            if (input.value.trim() !== '') {\n                sendAnswer(input.value.trim());\n                input.value = '';\n            }\n        });\n\n    })();\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-734","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/pages\/734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/comments?post=734"}],"version-history":[{"count":16,"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/pages\/734\/revisions"}],"predecessor-version":[{"id":751,"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/pages\/734\/revisions\/751"}],"wp:attachment":[{"href":"https:\/\/luplo.net\/index.php\/wp-json\/wp\/v2\/media?parent=734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}