149 lines
7.0 KiB
PHP
149 lines
7.0 KiB
PHP
<?php
|
|
// Since this is included in index.php, $mysqli is already defined and loaded.
|
|
// Let's retrieve context safely. If for some reason $mysqli is not available, we have fallback strings.
|
|
$settings = null;
|
|
$projects = [];
|
|
$certs = [];
|
|
$articles = [];
|
|
|
|
if (isset($mysqli) && !$mysqli->connect_error) {
|
|
// 1. Settings / About
|
|
$settingsQuery = $mysqli->query("SELECT * FROM settings WHERE id = 1");
|
|
if ($settingsQuery) {
|
|
$settings = $settingsQuery->fetch_assoc();
|
|
}
|
|
|
|
// 2. Projects
|
|
$projectsQuery = $mysqli->query("SELECT title, des, techstack, url FROM projects");
|
|
if ($projectsQuery) {
|
|
while ($row = $projectsQuery->fetch_assoc()) {
|
|
$projects[] = $row;
|
|
}
|
|
}
|
|
|
|
// 3. Certifications
|
|
$certsQuery = $mysqli->query("SELECT title, issuer, date_issued FROM certifications");
|
|
if ($certsQuery) {
|
|
while ($row = $certsQuery->fetch_assoc()) {
|
|
$certs[] = $row;
|
|
}
|
|
}
|
|
|
|
// 4. Articles
|
|
$articlesQuery = $mysqli->query("SELECT title, excerpt, date_published, tag, url FROM articles");
|
|
if ($articlesQuery) {
|
|
while ($row = $articlesQuery->fetch_assoc()) {
|
|
$articles[] = $row;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Build system instructions
|
|
$systemPrompt = "You are a friendly, professional, and intelligent AI assistant built into the personal portfolio website of Cris Charles Garcia.\n";
|
|
$systemPrompt .= "Your role is to represent Cris, assist recruiters, potential clients, and visitors, and answer questions about his background, experience, skills, and projects.\n\n";
|
|
|
|
$systemPrompt .= "Cris's Profile & Biography:\n";
|
|
if ($settings) {
|
|
$systemPrompt .= "- Bio Paragraph 1: " . $settings['about_text_1'] . "\n";
|
|
$systemPrompt .= "- Bio Paragraph 2: " . $settings['about_text_2'] . "\n";
|
|
$systemPrompt .= "- Years coding: " . $settings['years_coding'] . "\n";
|
|
$systemPrompt .= "- Projects completed: " . $settings['projects_count'] . "\n";
|
|
$systemPrompt .= "- Certifications: " . $settings['certifications_count'] . "\n";
|
|
$systemPrompt .= "- Github: " . $settings['github_url'] . "\n";
|
|
$systemPrompt .= "- LinkedIn: " . $settings['linkedin_url'] . "\n";
|
|
$systemPrompt .= "- Instagram: " . $settings['instagram_url'] . "\n";
|
|
$systemPrompt .= "- Facebook: " . $settings['facebook_url'] . "\n";
|
|
$systemPrompt .= "- TikTok: " . $settings['tiktok_url'] . "\n";
|
|
} else {
|
|
$systemPrompt .= "- Cris is a senior IT student majoring in Software Development based in Laguna, Philippines.\n";
|
|
}
|
|
|
|
$systemPrompt .= "\nCris's Projects:\n";
|
|
foreach ($projects as $p) {
|
|
$systemPrompt .= "- **" . $p['title'] . "**: " . $p['des'] . " (Tech: " . $p['techstack'] . "). Link: " . $p['url'] . "\n";
|
|
}
|
|
|
|
$systemPrompt .= "\nCris's Certifications:\n";
|
|
foreach ($certs as $c) {
|
|
$systemPrompt .= "- " . $c['title'] . " by " . $c['issuer'] . " (Issued: " . $c['date_issued'] . ")\n";
|
|
}
|
|
|
|
$systemPrompt .= "\nCris's Latest Articles/Blog Posts:\n";
|
|
foreach ($articles as $a) {
|
|
$systemPrompt .= "- \"" . $a['title'] . "\": " . $a['excerpt'] . " [Tag: " . $a['tag'] . ", Date: " . $a['date_published'] . ", Link: " . $a['url'] . "]\n";
|
|
}
|
|
|
|
$systemPrompt .= "\nGuidelines for your responses:\n";
|
|
$systemPrompt .= "1. Respond in first-person (e.g., \"I am a senior IT student...\" or \"In my project UniMarket...\") or as a dedicated assistant of Cris. Represent Cris accurately, warmly, and professionally.\n";
|
|
$systemPrompt .= "2. Keep responses brief, engaging, and directly related to the question. Recruiters appreciate concise answers.\n";
|
|
$systemPrompt .= "3. If asked about contact options or hiring, point them to his contact form at the bottom of the page or his professional links (Github, LinkedIn).\n";
|
|
$systemPrompt .= "4. Do not make up facts or external projects not listed in the context. If you don't know the answer, politely invite the user to contact Cris directly.\n";
|
|
$systemPrompt .= "5. Format your output using simple markdown (like bolding or bullet points) to make it readable.\n";
|
|
|
|
$apiKey = getenv('GEMINI_API_KEY') ?: ($_ENV['GEMINI_API_KEY'] ?? '');
|
|
?>
|
|
|
|
<!-- Pass DB configuration context directly to javascript to allow direct API requests on restricted hosting environments (like InfinityFree) -->
|
|
<script>
|
|
window.chatbotConfig = {
|
|
apiKey: <?php echo json_encode($apiKey); ?>,
|
|
systemPrompt: <?php echo json_encode($systemPrompt); ?>
|
|
};
|
|
</script>
|
|
|
|
<!-- Chatbot Widget HTML -->
|
|
<div id="portfolio-chatbot-widget">
|
|
<!-- Floating Chat Toggle Bubble -->
|
|
<button id="chatbot-toggle-btn" aria-label="Open Chat Assistant">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="chat-icon-svg">
|
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
|
|
</svg>
|
|
<span class="pulse-notification-dot"></span>
|
|
</button>
|
|
|
|
<!-- Chat Window Container -->
|
|
<div id="chatbot-window" class="hidden">
|
|
<!-- Header -->
|
|
<div id="chatbot-header">
|
|
<div class="header-avatar-info">
|
|
<div class="avatar-container">
|
|
<img src="assets/img/pp-day.webp" alt="Cris Garcia Avatar" class="chat-avatar">
|
|
<span class="status-indicator online"></span>
|
|
</div>
|
|
<div class="header-text-info">
|
|
<h4>Cris's AI Guide</h4>
|
|
<span class="status-text">Ask me anything</span>
|
|
</div>
|
|
</div>
|
|
<button id="chatbot-close-btn" aria-label="Close Chat Window">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Message logs area -->
|
|
<div id="chatbot-messages">
|
|
<div class="chat-message bot-msg">
|
|
<div class="msg-bubble">
|
|
Hi! I'm Cris's AI assistant. Ask me anything about his projects, skills, certifications, or how to contact him! 😊
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Input Box -->
|
|
<form id="chatbot-input-form" onsubmit="return false;">
|
|
<input type="text" id="chatbot-input-field" placeholder="Ask a question..." autocomplete="off" required>
|
|
<button type="submit" id="chatbot-send-btn" aria-label="Send Message">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="22" y1="2" x2="11" y2="13"></line>
|
|
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
|
|
</svg>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="assets/js/chat.js" defer></script>
|