77 lines
2.4 KiB
HTML
77 lines
2.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Searchcraft UI</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
</head>
|
|
<body class="bg-gray-900 text-white min-h-screen flex items-center justify-center px-4">
|
|
<div class="w-full max-w-2xl text-center">
|
|
<h1 class="text-3xl font-bold mb-6">🔍 Searchcraft</h1>
|
|
<input
|
|
id="search-query"
|
|
type="text"
|
|
placeholder="Start typing to search..."
|
|
class="w-full p-4 text-lg rounded-md bg-gray-800 border border-gray-700 focus:outline-none focus:ring-2 focus:ring-cyan-500"
|
|
oninput="debouncedSearch()"
|
|
/>
|
|
<div id="results" class="mt-8 space-y-4 text-left"></div>
|
|
</div>
|
|
|
|
<script>
|
|
const BASE_URL = "http://0.0.0.0:8000";
|
|
const INDEX = "thoughts-links";
|
|
let debounceTimer = null;
|
|
|
|
function debouncedSearch() {
|
|
clearTimeout(debounceTimer);
|
|
debounceTimer = setTimeout(search, 300);
|
|
}
|
|
|
|
async function search() {
|
|
const query = document.getElementById("search-query").value;
|
|
const resBox = document.getElementById("results");
|
|
resBox.innerHTML = '';
|
|
|
|
if (!query) return;
|
|
|
|
const response = await fetch(`${BASE_URL}/index/${INDEX}/search`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
limit: 10,
|
|
offset: 0,
|
|
query: { fuzzy: { ctx: query } }
|
|
}),
|
|
});
|
|
|
|
const result = await response.json();
|
|
const hits = result?.data?.hits || [];
|
|
|
|
for (const hit of hits) {
|
|
const { title, body, url } = hit.doc;
|
|
const preview = (body || "(no body)").slice(0, 1000) + ((body && body.length > 1000) ? "..." : "");
|
|
const link = url || "#";
|
|
|
|
const card = document.createElement("a");
|
|
card.href = link;
|
|
card.target = "_blank";
|
|
card.rel = "noopener noreferrer";
|
|
card.className = "block p-4 bg-gray-800 border border-gray-700 rounded-md hover:border-cyan-500 transition";
|
|
|
|
const titleEl = document.createElement("h3");
|
|
titleEl.className = "text-xl font-semibold text-cyan-400 mb-2";
|
|
titleEl.textContent = title || "Untitled";
|
|
|
|
const bodyEl = document.createElement("p");
|
|
bodyEl.className = "text-gray-300";
|
|
bodyEl.textContent = preview;
|
|
|
|
card.appendChild(titleEl);
|
|
card.appendChild(bodyEl);
|
|
resBox.appendChild(card);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|