Elementor Page #376

Kingdom Companion Chat (AI Powered) :root { --bg: #0f1216; --panel: #1c1f24; --ink: #ffffff; --accent: #5ab0ff; --bubble: #2a2d33; --companion: #ffd700; } body { font-family: Arial, sans-serif; background:var(--bg); color:var(--ink); margin:0; } .chat-container { display:flex; flex-direction:column; height:100vh; } header { background:var(--panel); padding:16px 20px; border-bottom:1px solid #23262b; } header h1 { margin:0; font-size:20px; } header p { margin:6px 0 0; color:#bfbfbf; font-size:13px; } .messages { flex:1; overflow-y:auto; padding:20px; } .message { margin:10px 0; max-width:70%; padding:10px; border-radius:10px; line-height:1.4; } .user { background:var(--accent); color:#0f1216; align-self:flex-end; border-bottom-right-radius:4px; } .companion { background:var(--bubble); color:var(--companion); align-self:flex-start; border-bottom-left-radius:4px; } .system { background:#24303b; color:#9ad1ff; align-self:center; font-size:12px; max-width:60%; } .input-bar { display:flex; gap:10px; padding:12px; background:var(--panel); border-top:1px solid #23262b; } .input-bar select, .input-bar input { padding:10px; border:none; border-radius:6px; background:#2a2d33; color:#fff; } .input-bar input { flex:1; } .btn { padding:10px 16px; border:none; border-radius:6px; background:var(--accent); color:#0f1216; font-weight:bold; cursor:pointer; } .btn:hover { background:#0077cc; color:#fff; } .status { font-size:12px; color:#9ad1ff; align-self:center; } .coaching { background:var(--panel); padding:16px; text-align:center; border-top:1px solid #23262b; } .coaching h3 { margin:4px 0 8px; } .coaching p { margin:6px 0; color:#bfbfbf; } .coaching .book { background:#ffd700; color:#0f1216; font-weight:bold; border:none; padding:12px 24px; border-radius:8px; cursor:pointer; } .coaching .book:hover { background:#e6c200; }

Kingdom Companion

Speak or type your heart. Your companion responds with empathy, guidance, and scripture.

Grace (Female Companion) Eli (Male Companion)

Need more support?

Book a one‑on‑one live coaching session with a Kingdom Companion.

$159 per hour

// Elements const messagesDiv = document.getElementById('messages'); const input = document.getElementById('chatInput'); const sendBtn = document.getElementById('sendBtn'); const micBtn = document.getElementById('micBtn'); const companionSelect = document.getElementById('companionGender'); // Local persistence let chatLog = JSON.parse(localStorage.getItem('kingdomChat')) || []; function saveChat() { localStorage.setItem('kingdomChat', JSON.stringify(chatLog)); } // Scripture pool appended to every reply (after AI text) const scriptures = [ "Psalm 34:18 — The Lord is close to the brokenhearted.", "Isaiah 41:10 — Do not fear, for I am with you.", "Matthew 11:28 — Come to me, all who are weary, and I will give you rest.", "Proverbs 3:5–6 — Trust in the Lord with all your heart; He will make your paths straight.", "Romans 8:28 — In all things God works for the good of those who love Him.", "Jeremiah 29:11 — For I know the plans I have for you.", "2 Corinthians 12:9 — My grace is sufficient for you.", "Philippians 4:6 — Present your requests to God.", "Hebrews 6:19 — We have this hope as an anchor for the soul.", "John 14:27 — My peace I give you; do not be afraid." ]; const randomScripture = () => scriptures[Math.floor(Math.random() * scriptures.length)]; // Chat rendering function addMessage(text, type = 'system') { const div = document.createElement('div'); div.className = 'message ' + type; div.innerHTML = text; messagesDiv.appendChild(div); messagesDiv.scrollTop = messagesDiv.scrollHeight; } function renderHistory() { chatLog.forEach(m => addMessage(m.text, m.role)); } renderHistory(); // Voice output function speakReply(text, gender) { try { const utterance = new SpeechSynthesisUtterance(text.replace(/
/g, " ")); const voices = speechSynthesis.getVoices(); let chosen = null; if (gender === "male") { chosen = voices.find(v => /Male|David|Google UK English Male|English Male/i.test(v.name)) || voices[0]; } else { chosen = voices.find(v => /Female|Zira|Samantha|Google US English|English Female/i.test(v.name)) || voices[0]; } if (chosen) utterance.voice = chosen; utterance.rate = 1.0; utterance.pitch = gender === "male" ? 0.95 : 1.05; speechSynthesis.cancel(); speechSynthesis.speak(utterance); } catch (e) { /* silent */ } } // Compose persona/system instructions for backend function buildSystemPrompt(gender) { const name = gender === 'male' ? 'Eli' : 'Grace'; return ` You are ${name}, the Kingdom Companion — a compassionate spiritual guide. Respond with: - Empathy that reflects the user's feelings without judgment. - Scripture (but the client will append one verse at the end; you may reference scripture naturally). - One gentle, open-ended follow-up question. Style guidelines: - Warm, concise, and human. - Avoid medical or legal advice. - Never give specific treatment recommendations. - Keep to 2–4 short paragraphs max. `; } // Call your AI backend (replace URL and payload as needed) async function getAIReply(userText, gender) { const systemPrompt = buildSystemPrompt(gender); // IMPORTANT: Replace /api/kingdom-companion with your real endpoint. // Backend should return JSON: { reply: "string" } const res = await fetch('/api/kingdom-companion', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ system: systemPrompt, user: userText, companion: gender // optional hint to backend }) }); if (!res.ok) { const msg = `Sorry, I’m having trouble responding right now. Please try again.`; return msg; } const data = await res.json(); const aiText = (data.reply || '').trim(); // Append scripture on the client side const scripture = randomScripture(); return `${aiText}
${scripture}`; } // Send message flow async function handleSend() { const text = input.value.trim(); const gender = companionSelect.value; const name = gender === 'male' ? 'Eli' : 'Grace'; if (!text) return; // Add user message addMessage(text, 'user'); chatLog.push({ role: 'user', text }); // Show typing indicator const typingEl = document.createElement('div'); typingEl.className = 'message system'; typingEl.innerHTML = `${name} is typing...`; messagesDiv.appendChild(typingEl); messagesDiv.scrollTop = messagesDiv.scrollHeight; input.value = ''; // Get AI reply let reply; try { reply = await getAIReply(text, gender); } catch (e) { reply = `I’m here with you. Let’s try again in a moment.
${randomScripture()}`; } // Remove typing indicator and add companion message messagesDiv.removeChild(typingEl); const formatted = `${name} says: ${reply}`; addMessage(formatted, 'companion'); chatLog.push({ role: 'companion', text: formatted }); saveChat(); // Speak reply speakReply(formatted, gender); } sendBtn.addEventListener('click', handleSend); input.addEventListener('keypress', (e) => { if (e.key === 'Enter') handleSend(); }); // Microphone (Web Speech API) const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; if (SpeechRecognition) { const recognition = new SpeechRecognition(); recognition.lang = "en-US"; recognition.interimResults = false; recognition.maxAlternatives = 1; micBtn.addEventListener("click", () => { try { recognition.start(); } catch (err) { alert("Mic could not start."); } }); recognition.addEventListener("result", (event) => { const transcript = event.results?.[0]?.[0]?.transcript || ""; input.value = transcript; }); } else { micBtn.addEventListener("click", () => alert("Mic not supported in this browser. Try Chrome or Edge.")); } // Coaching button document.getElementById('bookSessionBtn').addEventListener('click', () => { const proceed = confirm("You are about to book a live coaching session for $159/hour. Continue?"); if (proceed) window.location.href = "https://yourwebsite.com/book-session"; // replace with your booking link }); // Ensure voices are loaded if (typeof speechSynthesis !== "undefined") { speechSynthesis.onvoiceschanged = () => {}; }