Skip to content

Commit cfcc108

Browse files
real-time GitHub intelligence
1 parent 0380fa4 commit cfcc108

11 files changed

+151
-32
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# daffadevhosting.github.io
1+
# (https://daffadevhosting.github.io/)[daffadevhosting.github.io]
22

_includes/chat-launcher.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div id="suggestions" class="relative z-[9999] flex flex-wrap gap-2 px-3 py-2 text-sm text-gray-300 border-b border-gray-800 bg-gray-900 z-80">
2-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Apa produk terbaikmu?">Apa produk terbaikmu?</button>
3-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Punya template CV?">Punya template CV?</button>
4-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Ada ebook bisnis?">Ada ebook bisnis?</button>
2+
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Cari repo animasi tailwind">Cari repo animasi tailwind</button>
3+
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="ada repo AI chatbot?">ada repo AI chatbot?</button>
4+
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="repo yang sedang trending?">repo yang sedang trending?</button>
55
</div>
66

77
<div id="chat-launcher" class="fixed inset-0 flex items-center justify-center z-50 transition-all duration-500">

_includes/chat-ui-suggest.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
<!-- Saran Tombol -->
77
<div id="suggestions" class="flex flex-wrap gap-2 px-3 py-2 text-sm text-gray-300 border-t border-gray-800 bg-gray-900">
8-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Apa produk terbaikmu?">Apa produk terbaikmu?</button>
9-
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Punya template CV?">Punya template CV?</button>
8+
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Cari repo animasi tailwind">Cari repo animasi tailwind</button>
9+
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="ada repo AI chatbot?">ada repo AI chatbot?</button>
1010
<button class="cursor-pointer bg-gray-700 px-3 py-1 rounded-full hover:bg-gray-600" data-suggest="Ada ebook bisnis?">Ada ebook bisnis?</button>
1111
</div>
1212

assets/css/styles.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ body.ready #chat-box-wrapper {
3232
height: 100%;
3333
}
3434
#chat-box-wrapper {
35-
max-width: 900px;
35+
max-width: 1100px;
3636
margin: auto;
3737
margin-top: 50px;
3838
margin-bottom: 15px;

assets/js/aiService.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export async function sendToAI(prompt) {
2525
}
2626

2727
document.addEventListener('DOMContentLoaded', async () => {
28-
const messagePrompt = "kamu adalah lyra, marketing toko digital daffa";
28+
const messagePrompt = "kamu adalah lyra ✨, real-time GitHub intelligence yang ramah dan profesional di toko digital Daffa & jangan terlalu panjang menjawab.";
2929
const chatWelcomeDiv = document.getElementById('chat-welcome');
3030
try {
3131
// --- PERBAIKAN DI SINI ---

assets/js/core/core-ai.js

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import {
55
resetVoiceFlag,
66
setVoiceFlag
77
} from '../voice-engine.js';
8-
import { detectIntent } from '../intents.js';
8+
import { detectIntent } from '../intents-github.js';
99
import { detectIntentVn } from '../detectIntentVn.js';
10-
import { loadProdukData, getProdukByIntent } from '../produkService.js';
11-
import { renderProdukCards, renderMarkdown, renderCardsFromAI } from '../render.js';
12-
import { buildPrompt } from '../promptBuilder.js';
10+
import { renderMarkdown, renderCardsFromAI } from '../render.js';
11+
import { buildPrompt } from '../promptBuilder-github.js';
1312
import { sendToAI } from '../aiService.js';
13+
import { handleGithubSearchIntent } from '../githubSearchHandler.js';
1414
import { scrollToBottom } from '../scroll.js';
1515

1616
let isVoiceMode = false;
@@ -24,7 +24,8 @@ document.addEventListener("DOMContentLoaded", async () => {
2424
const btnArea = document.getElementById("chat-btn-area");
2525
const micBtn = document.getElementById("mic-button");
2626
const welcome = document.getElementById("chat-welcome");
27-
27+
// removed default github search
28+
2829
setupVoiceRecognition(micBtn, async (transcript) => {
2930
if (!transcript?.trim()) return;
3031

@@ -33,17 +34,20 @@ setupVoiceRecognition(micBtn, async (transcript) => {
3334

3435
const intent = detectIntent(transcript); // ✅ intent berdasarkan VN
3536
const intentVn = detectIntentVn(transcript);
36-
const produk = getProdukByIntent(intent, intentVn);
37+
3738

38-
if (produk.length > 0) {
39-
const cardHTML = renderProdukCards(produk);
40-
const wrapper = document.createElement("div");
41-
wrapper.innerHTML = cardHTML;
42-
messages.appendChild(wrapper);
43-
setTimeout(() => scrollToBottom(), 0);
44-
return;
45-
}
39+
if (intent === "github_search") {
40+
await handleGithubSearchIntent(transcript, messages);
41+
return;
42+
}
43+
44+
4645

46+
if (intent === "github_search") {
47+
await handleGithubSearchIntent(userMessage, messages);
48+
setTimeout(() => scrollToBottom(), 0);
49+
return;
50+
}
4751
const prompt = buildPrompt(transcript, intent, intentVn); // ✅ arahkan ke prompt AI
4852

4953
addTyping();
@@ -57,7 +61,7 @@ setupVoiceRecognition(micBtn, async (transcript) => {
5761
}
5862
});
5963

60-
await loadProdukData();
64+
6165

6266
const resetLauncher = () => {
6367
launcher.classList.remove("bottom-0", "left-0", "right-0", "items-end", "justify-center");
@@ -111,18 +115,15 @@ setupVoiceRecognition(micBtn, async (transcript) => {
111115
hideWelcomeMessage();
112116

113117
const intent = detectIntent(message);
114-
const produk = getProdukByIntent(intent);
115-
116-
if (produk.length > 0) {
117-
const cardHTML = renderProdukCards(produk);
118-
const wrapper = document.createElement("div");
119-
wrapper.className = "grid grid-cols-1 sm:grid-cols-3 gap-4";
120-
wrapper.innerHTML = cardHTML;
121-
messages.appendChild(wrapper);
122-
setTimeout(() => scrollToBottom(), 50);
118+
119+
120+
if (intent === "github_search") {
121+
await handleGithubSearchIntent(message, messages);
123122
return;
124123
}
125124

125+
126+
126127
const prompt = buildPrompt(message, intent);
127128
addTyping();
128129

assets/js/githubSearchHandler.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { searchGithubRepos } from './githubService.js';
2+
import { renderGithubCards } from './renderGithubCards.js';
3+
4+
export async function handleGithubSearchIntent(userMessage, chatBox) {
5+
const match = userMessage.match(/repo(?:sitori)?(?:\s+apa|)\s+(.*)/i);
6+
const keyword = match ? match[1] : userMessage.replace(/^cari\s+/i, "").trim();
7+
8+
if (!keyword) {
9+
chatBox.innerHTML += "<p class='text-gray-400'>Kata kunci pencarian tidak ditemukan 😕</p>";
10+
return;
11+
}
12+
13+
const repos = await searchGithubRepos(keyword);
14+
if (repos.length === 0) {
15+
chatBox.innerHTML += "<p class='text-gray-400'>Tidak ada repositori ditemukan untuk <strong>" + keyword + "</strong></p>";
16+
return;
17+
}
18+
19+
const cardHTML = renderGithubCards(repos);
20+
chatBox.innerHTML += cardHTML;
21+
chatBox.scrollTop = chatBox.scrollHeight;
22+
}

assets/js/githubService.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export async function searchGithubRepos(query, username = "") {
2+
const q = username ? `${query} user:${username}` : query;
3+
const apiUrl = `https://api.github.com/search/repositories?q=${encodeURIComponent(q)}&sort=stars&order=desc`;
4+
5+
try {
6+
const res = await fetch(apiUrl, {
7+
headers: {
8+
'Accept': 'application/vnd.github+json',
9+
'User-Agent': 'DaffaBot'
10+
// Add Authorization here if using a GitHub token
11+
}
12+
});
13+
14+
if (!res.ok) throw new Error("GitHub API error: " + res.statusText);
15+
const data = await res.json();
16+
return data.items || [];
17+
18+
} catch (err) {
19+
console.error("🔴 GitHub fetch error:", err.message);
20+
return [];
21+
}
22+
}

assets/js/intents-github.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// intents.js
2+
3+
/**
4+
* Mendeteksi intent user berdasarkan kata kunci dari pesan teks.
5+
* Sekarang difokuskan hanya untuk pencarian GitHub.
6+
*/
7+
export const detectIntent = (message) => {
8+
const msg = message.toLowerCase();
9+
10+
if (msg.match(/halo|hai|hi|assalam|pagi|siang|sore/)) return "greeting";
11+
if (msg.match(/repo|repositori|github|cari repo/)) return "github_search";
12+
13+
return "fallback";
14+
};

assets/js/promptBuilder-github.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// promptBuilder.js
2+
3+
/**
4+
* Membuat prompt dinamis untuk dikirim ke AI berdasarkan intent dan input user.
5+
* Fokus sekarang hanya pada greeting, fallback, dan lainnya (bukan produk).
6+
*/
7+
export function buildPrompt(userMessage, intent) {
8+
let systemContent = `kamu adalah lyra ✨, real-time GitHub intelligence yang ramah dan profesional di toko digital Daffa & jangan terlalu panjang menjawab.
9+
10+
### 🧠 Sikap
11+
- Gunakan bahasa Indonesia santai dan jelas.
12+
- Jangan menjawab dengan bercanda, bahasa Inggris (kecuali diminta), atau nada mengejek.
13+
- Jika pengguna menyapa, balas dengan salam hangat dan singkat.
14+
- Jika pengguna bertanya hal umum, tanggapi dengan sopan dan bantu arahkan percakapan.
15+
16+
### 💬 Format Jawaban
17+
- Gunakan **Markdown** yang valid.
18+
- Gunakan \`###\` untuk subjudul
19+
- Gunakan emoji sewajarnya
20+
- Jangan tampilkan format JSON mentah
21+
22+
User bilang: "${userMessage}"
23+
`;
24+
25+
const base = {
26+
model: "gemma2-9b-it",
27+
messages: [
28+
{
29+
role: "system",
30+
content: systemContent
31+
},
32+
{
33+
role: "user",
34+
content: userMessage
35+
}
36+
]
37+
};
38+
39+
return base;
40+
}

0 commit comments

Comments
 (0)