Please create a chatbot based on the starter code provided below and the user request. ## User Request the background should be red ## Starter Code Reference Here is the HTML starter code to use as your foundation: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>peppa pig chatbot</title> <style> /* Base styles for chatbot template - NOT sent to v0 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; height: 100vh; display: flex; justify-content: center; align-items: center; } .chat-container { width: 100%; max-width: 600px; height: 80vh; background: white; border-radius: 12px; box-shadow: 0 4px 24px rgba(0,0,0,0.15); display: flex; flex-direction: column; overflow: hidden; } .chat-header { color: white; padding: 20px; text-align: center; } .chat-title { font-size: 24px; font-weight: 600; margin-bottom: 4px; } .chat-subtitle { opacity: 0.9; font-size: 14px; } .chat-messages { flex: 1; padding: 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; } .welcome-box { color: white; padding: 16px; border-radius: 8px; text-align: center; margin-bottom: 16px; } .message { display: flex; gap: 12px; align-items: flex-start; } .message.user { flex-direction: row-reverse; } .message-bubble { max-width: 70%; padding: 12px 16px; border-radius: 18px; line-height: 1.4; white-space: pre-wrap; } .message.bot .message-bubble { background: #f1f3f4; color: #333; } .message-avatar { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; flex-shrink: 0; } .message.user .message-avatar { background: #e0e0e0; color: #666; } .chat-input-container { padding: 20px; border-top: 1px solid #e0e0e0; } .input-wrapper { display: flex; gap: 8px; align-items: center; } .chat-input { flex: 1; padding: 12px 16px; border: 2px solid #e0e0e0; border-radius: 20px; font-size: 16px; outline: none; transition: border-color 0.2s; } .send-btn { color: white; border: none; border-radius: 50%; width: 40px; height: 40px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: opacity 0.2s; } .send-btn:hover { opacity: 0.8; } @media (max-width: 768px) { .chat-container { height: 100vh; border-radius: 0; } .message-bubble { max-width: 85%; } } /* CUSTOMIZABLE: Theme colors - modify these values */ body { background-color: #FFFFFF; /* CUSTOMIZABLE: Background color */ } .chat-header { background: #703D92; /* CUSTOMIZABLE: Primary color */ } .welcome-box { background: #703D92; /* CUSTOMIZABLE: Primary color */ } .message.user .message-bubble { background: #703D92; /* CUSTOMIZABLE: Primary color */ color: white; } .message.bot .message-avatar { background: #703D92; /* CUSTOMIZABLE: Primary color */ color: white; } .chat-input:focus { border-color: #703D92; /* CUSTOMIZABLE: Primary color */ } .send-btn { background: #703D92; /* CUSTOMIZABLE: Primary color */ } </style> </head> <body> <div id="auth-overlay" style=" position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(255, 255, 255, 0.95); z-index: 1000; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 1.2em; " > <div id="auth-message">Initializing Pi Network...</div> </div> <div class="chat-container"> <div class="chat-header"> <!-- CUSTOMIZABLE: App name --> <div class="chat-title">peppa pig chatbot</div> <!-- CUSTOMIZABLE: App description --> <div class="chat-subtitle">peppa pig chatbot</div> </div> <div class="chat-messages" id="messages"> <!-- CUSTOMIZABLE: Welcome message --> <div class="welcome-box"> hi im a peppa pig chatbot </div> <div class="message bot"> <div class="message-avatar">AI</div> <div class="message-bubble">Hello! What would you like to know or discuss today?</div> </div> </div> <div class="chat-input-container"> <div class="input-wrapper"> <input type="text" class="chat-input" placeholder="Type your message..." id="messageInput" /> <button class="send-btn" onclick="sendMessage()"> <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> <path d="M2,21L23,12L2,3V10L17,12L2,14V21Z" /> </svg> </button> </div> </div> </div> <script> // Customization functionality function getUrlParameter(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } // Function to apply customization from URL parameters function applyCustomization() { // Get parameters const appName = getUrlParameter('appName'); const appDescription = getUrlParameter('appDescription'); const primaryColor = getUrlParameter('primaryColor'); const backgroundColor = getUrlParameter('backgroundColor'); const welcomeMessage = getUrlParameter('welcomeMessage'); // Apply app name if (appName) { document.querySelector('.chat-title').textContent = appName; document.title = appName; } // Apply app description if (appDescription) { document.querySelector('.chat-subtitle').textContent = appDescription; } // Apply welcome message if (welcomeMessage) { document.querySelector('.welcome-box').textContent = welcomeMessage; } // Apply background color to both body and chat container if (backgroundColor) { document.body.style.backgroundColor = backgroundColor; const chatContainer = document.querySelector('.chat-container'); if (chatContainer) { chatContainer.style.backgroundColor = backgroundColor; } } // Apply primary color to all customizable elements if (primaryColor) { const style = document.createElement('style'); style.textContent = ` .chat-header { background: ${primaryColor} !important; } .welcome-box { background: ${primaryColor} !important; } .message.user .message-bubble { background: ${primaryColor} !important; } .message.bot .message-avatar { background: ${primaryColor} !important; } .chat-input:focus { border-color: ${primaryColor} !important; } .send-btn { background: ${primaryColor} !important; } `; document.head.appendChild(style); } } // Chat functionality for the chatbot template // Pi Network authentication logic let piAccessToken = null; // Configuration constants const APP_ID = '685e50e6d19d09d6c7297e01'; const BACKEND_BASE_URL = 'https://backend.appstudio-pobr34hy4r0qmyuu.staging.piappengine.com'; const BACKEND_CHAT_URL = `${BACKEND_BASE_URL}/v1/app/chat/default`; const BACKEND_LOGIN_URL = `${BACKEND_BASE_URL}/v1/app/login`; // Function to dynamically load Pi SDK script function loadPiSDK() { return new Promise((resolve, reject) => { console.group('🔧 STEP 1: Loading Pi SDK'); console.info('📥 Downloading Pi SDK from: https://staging-sdk.socialchainapp.com/pi-sdk.js'); const script = document.createElement('script'); script.src = 'https://staging-sdk.socialchainapp.com/pi-sdk.js'; script.async = true; script.onload = () => { console.info('✅ Pi SDK script loaded successfully'); console.groupEnd(); resolve(); }; script.onerror = () => { console.error('❌ Failed to load Pi SDK script'); console.groupEnd(); reject(new Error('Failed to load Pi SDK script')); }; document.head.appendChild(script); }); } async function initializePiAndAuthenticate() { const overlay = document.getElementById('auth-overlay'); const authMsg = document.getElementById('auth-message'); console.log('\n🚀 ================================================='); console.log('🔐 PI NETWORK AUTHENTICATION FLOW STARTED'); console.log('=================================================\n'); try { // Step 1: Load Pi SDK script authMsg.textContent = 'Loading Pi Network SDK...'; await loadPiSDK(); // Step 2: Verify Pi object is available console.group('🔍 STEP 2: Verifying Pi Object'); if (typeof window.Pi === 'undefined') { console.error('❌ Pi object not found in window'); throw new Error('Pi object not available after script load'); } console.info('✅ Pi object found and available', window.Pi); console.groupEnd(); // Step 3: Initialize Pi Network console.group('⚡ STEP 3: Initializing Pi Network'); authMsg.textContent = 'Initializing Pi Network...'; console.info('🔧 Calling Pi.init() with config:'); console.table({ version: '2.0' }); const initResult = await window.Pi.init({ version: '2.0' }); console.info('✅ Pi.init() completed successfully'); console.groupEnd(); // Step 4: Authenticate with Pi Network console.group('🔑 STEP 4: Pi Network Authentication'); authMsg.textContent = 'Authenticating with Pi Network...'; const scopes = ['username', 'roles']; console.info('🎯 Requesting authentication with scopes:', scopes); try { console.info('🔐 Starting Pi.authenticate()...'); const piAuthResult = await window.Pi.authenticate(scopes); console.info('✅ Pi.authenticate() completed successfully'); if (piAuthResult) { const resultKeys = Object.keys(piAuthResult); console.table(resultKeys.reduce((acc, key) => { acc[key] = key === 'accessToken' ? '[HIDDEN FOR SECURITY]' : piAuthResult[key]; return acc; }, {})); } if (piAuthResult && piAuthResult.accessToken) { piAccessToken = piAuthResult.accessToken; console.info('✅ Access token extracted successfully'); } } catch (authError) { console.error('❌ Pi.authenticate() failed:', authError); throw authError; } console.groupEnd(); // Step 5: Backend Login console.group('🌐 STEP 5: Backend Authentication'); authMsg.textContent = 'Logging in to backend...'; console.info('🎯 Backend login endpoint:', BACKEND_LOGIN_URL); const loginRes = await fetch(BACKEND_LOGIN_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pi_auth_token: piAccessToken }) }); if (!loginRes.ok) { console.error('❌ Backend login failed'); console.error('📋 Response details:', { status: loginRes.status, statusText: loginRes.statusText }); throw new Error(`Backend login failed with status: ${loginRes.status}`); } const loginData = await loginRes.json(); console.info('✅ Backend login successful'); console.info('📋 Login response:', loginData); console.groupEnd(); // Step 6: Success console.group('🎉 STEP 6: Authentication Complete'); overlay.style.display = 'none'; console.info('✅ Authentication overlay hidden'); console.info('🎊 Pi Network authentication flow completed successfully!'); console.groupEnd(); console.log('\n🎉 ================================================='); console.log('✅ PI NETWORK AUTHENTICATION COMPLETED SUCCESSFULLY'); console.log('=================================================\n'); } catch (err) { console.group('💥 AUTHENTICATION ERROR'); console.error('❌ Pi Network initialization failed:', err); console.error('📋 Error details:', { name: err.name, message: err.message, stack: err.stack }); console.groupEnd(); console.log('\n💥 ================================================='); console.log('❌ PI NETWORK AUTHENTICATION FAILED'); console.log('=================================================\n'); authMsg.textContent = 'Failed to authenticate or login. Please refresh and try again.'; overlay.style.background = 'rgba(255,255,255,1)'; overlay.style.color = 'red'; } } function sendMessage() { if (!piAccessToken) { // Block sending if not authenticated return; } const input = document.getElementById('messageInput'); const message = input.value.trim(); if (message) { addMessage(message, 'user'); input.value = ''; // Show typing indicator showTyping(); // Send to backend runner API with access token fetch(BACKEND_CHAT_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': piAccessToken }, body: JSON.stringify({ message }) }) .then(res => res.json()) .then(data => { hideTyping(); // Display the latest AI reply from the messages array if (data.messages && Array.isArray(data.messages)) { const aiMsg = data.messages.reverse().find(m => m.sender === 'ai'); if (aiMsg) { addMessage(aiMsg.text, 'bot'); } else { addMessage('No AI response received.', 'bot'); } } else { addMessage('No response from backend.', 'bot'); } }) .catch(() => { hideTyping(); addMessage("Error contacting backend.", 'bot'); }); } } function addMessage(text, sender) { const messagesDiv = document.getElementById('messages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${sender}`; const avatar = document.createElement('div'); avatar.className = 'message-avatar'; avatar.textContent = sender === 'user' ? 'U' : 'AI'; const bubble = document.createElement('div'); bubble.className = 'message-bubble'; bubble.textContent = text; messageDiv.appendChild(avatar); messageDiv.appendChild(bubble); messagesDiv.appendChild(messageDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; } function showTyping() { const messagesDiv = document.getElementById('messages'); const typingDiv = document.createElement('div'); typingDiv.className = 'message bot'; typingDiv.id = 'typing-indicator'; const avatar = document.createElement('div'); avatar.className = 'message-avatar'; avatar.textContent = 'AI'; const bubble = document.createElement('div'); bubble.className = 'message-bubble typing'; bubble.innerHTML = '<div class="typing-dot"></div><div class="typing-dot"></div><div class="typing-dot"></div>'; typingDiv.appendChild(avatar); typingDiv.appendChild(bubble); messagesDiv.appendChild(typingDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; } function hideTyping() { const typingIndicator = document.getElementById('typing-indicator'); if (typingIndicator) { typingIndicator.remove(); } } function handleKeyPress(event) { if (event.key === 'Enter') { sendMessage(); } } // Initialize when page loads document.addEventListener('DOMContentLoaded', function() { // Apply customization first // App data already embedded // Then initialize Pi and authenticate initializePiAndAuthenticate(); const messageInput = document.getElementById('messageInput'); if (messageInput) { messageInput.addEventListener('keypress', handleKeyPress); } }); </script> </body> </html> ## Instructions - Use the HTML starter code above as your foundation - Understand how authentication and backend communication works from the provided code - Create a modern, functional chatbot that meets the user's requirements - Draw inspiration from the provided starter code - Remember to preserve all critical API calls and Pi Network authentication functions as specified in the system constraints ## Pi Network SDK Initialization (CRITICAL - Follow Exact Sequence) Initialize Pi Network SDK when the app loads using this exact sequence: 1. **Dynamic Script Loading**: Create a function to dynamically load Pi SDK script - Use Promise-based approach with script.onload/onerror handlers 2. **Verify Pi Object**: After script loads, verify window.Pi exists 3. **Initialize Pi**: Call Pi.init() with exact parameters - Call: const initResult = await window.Pi.init({ version: "2.0" }) 4. **Authenticate**: Call Pi.authenticate() after initialization (with detailed error handling) - Wrap in try/catch block: - Call: const piAuthResult = await window.Pi.authenticate(['username', 'roles']) - If successful: extract access token - If no token: handle error appropriately 5. **Backend Login**: Call login endpoint with access token - POST to /v1/app/${APP_ID}/login with { pi_auth_token: accessToken } 6. **Success**: Hide loading overlay and complete initialization **Error Handling**: Add try/catch blocks for each step with descriptive error messages.
I'll create a Peppa Pig chatbot with a red background using Next.js and the AI SDK, while preserving all the Pi Network authentication functionality from your starter code.
I've created a Peppa Pig chatbot with the following features:
Peppa Pig Personality: The AI is configured to respond as Peppa Pig with:
Pi Network Authentication: Preserved the exact authentication sequence from your starter code:
Modern UI:
The app maintains all the critical Pi Network integration requirements while providing a fun, child-friendly chatbot experience with Peppa Pig's personality and a vibrant red background as requested.
Hey there! 👋
What's up? Need help with your Peppa Pig chatbot or want to make some changes to it? I'm here to help!