diff --git a/api/chat.php b/api/chat.php new file mode 100644 index 0000000..890b78c --- /dev/null +++ b/api/chat.php @@ -0,0 +1,75 @@ + [ + ['role' => 'system', 'content' => 'You are a cheerful and witty assistant who provides funny weekend wishes and suggests meme keywords in a structured JSON format.'], + ['role' => 'user', 'content' => $prompt], + ], + ]); + + $generatedText = "I'm a bit tired, but I wish you a fantastic weekend! Let's talk more on Monday."; + $memeKeyword = 'cat'; // Default keyword + + if (!empty($aiResponse['success'])) { + $jsonOutput = LocalAIApi::decodeJsonFromResponse($aiResponse); + if ($jsonOutput && isset($jsonOutput['wish']) && isset($jsonOutput['meme_keyword'])) { + $generatedText = $jsonOutput['wish']; + $memeKeyword = $jsonOutput['meme_keyword']; + } else { + $generatedText = LocalAIApi::extractText($aiResponse); // Fallback to raw text + } + } + + // 2. Fetch a meme image using the keyword + $memeData = null; + $pexelsUrl = 'https://api.pexels.com/v1/search?query=' . urlencode($memeKeyword) . '&orientation=portrait&per_page=1&page=1'; + $pexelsData = pexels_get($pexelsUrl); + + if ($pexelsData && !empty($pexelsData['photos'])) { + $photo = $pexelsData['photos'][0]; + $src = $photo['src']['large'] ?? $photo['src']['original']; + $memeData = [ + 'src' => $src, + 'photographer' => $photo['photographer'] + ]; + } else { + // Fallback image + $memeData = [ + 'src' => 'https://images.pexels.com/photos/1741205/pexels-photo-1741205.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940', + 'photographer' => 'Pexels' + ]; + } + + echo json_encode([ + 'success' => true, + 'message' => $generatedText, + 'meme' => $memeData + ]); + exit; +} + +echo json_encode(['success' => false, 'error' => 'Invalid action.']); diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..c2fa5a5 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,77 @@ + +body { + background-color: #f8f9fa; + font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; +} + +.hero { + background: linear-gradient(45deg, #6f42c1, #fd7e14); + color: white; + padding: 100px 0; + text-align: center; +} + +.chat-container { + max-width: 800px; + margin: 50px auto; + background-color: #ffffff; + border-radius: 0.75rem; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); +} + +.chat-header { + background-color: #6f42c1; + color: white; + padding: 1rem; + border-top-left-radius: 0.75rem; + border-top-right-radius: 0.75rem; + text-align: center; +} + +.chat-box { + height: 400px; + overflow-y: auto; + padding: 1rem; +} + +.chat-bubble { + margin-bottom: 1rem; + padding: 0.75rem 1.25rem; + border-radius: 0.75rem; + max-width: 75%; + line-height: 1.5; +} + +.chat-bubble.user { + background-color: #e9ecef; + color: #212529; + margin-left: auto; + text-align: right; +} + +.chat-bubble.ai { + background-color: #6f42c1; + color: white; + margin-right: auto; +} + +.chat-bubble.ai .meme { + max-width: 100%; + border-radius: 0.5rem; + margin-top: 0.5rem; +} + +.chat-input { + border-top: 1px solid #dee2e6; + padding: 1rem; +} + +.btn-primary { + background-color: #6f42c1; + border-color: #6f42c1; +} + +.btn-primary:hover { + background-color: #5a37a0; + border-color: #5a37a0; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..b24bf86 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,133 @@ + +document.addEventListener('DOMContentLoaded', () => { + const startChatBtn = document.getElementById('startChatBtn'); + const chatContainer = document.getElementById('chatContainer'); + const chatBox = document.getElementById('chatBox'); + const chatForm = document.getElementById('chatForm'); + const chatInput = document.getElementById('chatInput'); + + // Conversation context + let conversationState = 'initial'; // 'initial', 'asked_day', 'asked_profession', 'done' + let userDay = ''; + let userProfession = ''; + + if (startChatBtn) { + startChatBtn.addEventListener('click', () => { + chatContainer.scrollIntoView({ behavior: 'smooth' }); + if (conversationState === 'initial') { + setTimeout(() => { + addAiMessage('Hello there! How was your day?'); + conversationState = 'asked_day'; + }, 500); + } + }); + } + + chatForm.addEventListener('submit', (e) => { + e.preventDefault(); + const userMessage = chatInput.value.trim(); + if (userMessage) { + addUserMessage(userMessage); + chatInput.value = ''; + handleConversation(userMessage); + } + }); + + function handleConversation(userMessage) { + if (conversationState === 'asked_day') { + userDay = userMessage; + addAiMessage('Interesting! And what is your profession?'); + conversationState = 'asked_profession'; + } else if (conversationState === 'asked_profession') { + userProfession = userMessage; + conversationState = 'done'; + getAiResponse(); + } + } + + function getAiResponse() { + addAiMessage('Thinking of something funny...', 'typing'); + const formData = new FormData(); + formData.append('day', userDay); + formData.append('profession', userProfession); + + fetch('api/chat.php', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + removeTypingIndicator(); + if (data.success) { + addAiMeme(data.message, data.meme.src, data.meme.photographer); + addMoreButton(); + } else { + addAiMessage('Oops, my wires are crossed. Please try again!'); + } + }) + .catch(error => { + removeTypingIndicator(); + console.error('Error:', error); + addAiMessage('I seem to have lost my train of thought. Could you try again?'); + }); + } + + function addMoreButton() { + const moreButton = document.createElement('button'); + moreButton.textContent = 'Another one!'; + moreButton.className = 'btn btn-secondary btn-sm mt-2'; + moreButton.onclick = () => { + moreButton.remove(); + getAiResponse(); + }; + chatBox.appendChild(moreButton); + chatBox.scrollTop = chatBox.scrollHeight; + } + + function addUserMessage(message) { + const bubble = document.createElement('div'); + bubble.className = 'chat-bubble user'; + bubble.textContent = message; + chatBox.appendChild(bubble); + chatBox.scrollTop = chatBox.scrollHeight; + } + + function addAiMessage(message, id = null) { + const bubble = document.createElement('div'); + bubble.className = 'chat-bubble ai'; + if (id) bubble.id = id; + bubble.textContent = message; + chatBox.appendChild(bubble); + chatBox.scrollTop = chatBox.scrollHeight; + } + + function removeTypingIndicator() { + const typingBubble = document.getElementById('typing'); + if (typingBubble) { + typingBubble.remove(); + } + } + + function addAiMeme(text, imageUrl, photographer) { + const bubble = document.createElement('div'); + bubble.className = 'chat-bubble ai'; + + const textElement = document.createElement('p'); + textElement.textContent = text; + bubble.appendChild(textElement); + + const memeElement = document.createElement('img'); + memeElement.src = imageUrl; + memeElement.className = 'meme'; + memeElement.alt = `Meme for ${userProfession}`; + bubble.appendChild(memeElement); + + const credit = document.createElement('p'); + credit.className = 'text-muted small mt-2'; + credit.innerHTML = `Photo by ${photographer} on Pexels`; + bubble.appendChild(credit); + + chatBox.appendChild(bubble); + chatBox.scrollTop = chatBox.scrollHeight; + } +}); diff --git a/includes/pexels.php b/includes/pexels.php new file mode 100644 index 0000000..a12b74c --- /dev/null +++ b/includes/pexels.php @@ -0,0 +1,25 @@ + 0 ? $k : 'Vc99rnmOhHhJAbgGQoKLZtsaIVfkeownoQNbTj78VemUjKh08ZYRbf18'; + } + function pexels_get($url) { + $ch = curl_init(); + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTPHEADER => [ 'Authorization: '. pexels_key() ], + CURLOPT_TIMEOUT => 15, + ]); + $resp = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + if ($code >= 200 && $code < 300 && $resp) return json_decode($resp, true); + return null; + } + function download_to($srcUrl, $destPath) { + $data = file_get_contents($srcUrl); + if ($data === false) return false; + if (!is_dir(dirname($destPath))) mkdir(dirname($destPath), 0775, true); + return file_put_contents($destPath, $data) !== false; + } diff --git a/index.php b/index.php index 7205f3d..c9dd296 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,62 @@ - - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + MemeChat - Your Daily Dose of Humor + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- + + +
+

Welcome to MemeChat

+

Your AI companion for a brighter, funnier day.

+ +
+ + +
+
+
+
MemeChat AI
+
+
+ +
+
+
+ + +
+
+
+
+ + + + + + + + + - + \ No newline at end of file