Spaces:
Build error
Build error
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>HelpingAI Search</title> | |
<style> | |
body, | |
html { | |
margin: 0; | |
padding: 0; | |
font-family: "Arial", sans-serif; | |
height: 100%; | |
background: #f2f2f2; /* Light gray background */ | |
} | |
.container { | |
display: flex; | |
flex-direction: column; | |
min-height: 100%; | |
} | |
header { | |
padding: 30px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
background: #fff; /* White header background */ | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Subtle shadow */ | |
} | |
.main-content { | |
flex-grow: 1; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
padding: 40px 20px; /* Increased padding */ | |
} | |
.logo { | |
font-size: 40px; /* Reduced logo size */ | |
font-weight: bold; | |
margin-bottom: 20px; | |
color: #4285f4; | |
position: absolute; | |
left: 43vw; | |
top: 6px; | |
} | |
.logo span:nth-child(2) { | |
color: #ea4335; | |
} | |
.logo span:nth-child(3) { | |
color: #fbbc05; | |
} | |
.logo span:nth-child(4) { | |
color: #34a853; | |
} | |
.logo span:nth-child(5) { | |
color: #ea4335; | |
} | |
.search-container { | |
width: 100%; | |
max-width: 700px; | |
margin-bottom: 20px; | |
position: relative; /* For positioning suggestions */ | |
} | |
.search-box { | |
display: flex; | |
border: 1px solid #dfe1e5; | |
border-radius: 24px; | |
padding: 5px 8px; | |
transition: box-shadow 0.3s; | |
background: #fff; /* White search box background */ | |
} | |
.search-box:hover, | |
.search-box:focus-within { | |
box-shadow: 0 1px 6px rgba(32, 33, 36, 0.28); | |
border-color: rgba(223, 225, 229, 0); | |
} | |
#search-query { | |
flex-grow: 1; | |
border: none; | |
outline: none; | |
font-size: 16px; | |
padding: 10px 15px; | |
} | |
button { | |
background: none; | |
border: none; | |
cursor: pointer; | |
padding: 0 15px; | |
} | |
#search-form button svg { | |
width: 20px; /* Reduced icon size */ | |
height: 20px; | |
} | |
#suggestions { | |
width: 100%; | |
max-width: 700px; | |
border: 1px solid #dfe1e5; | |
border-top: none; | |
border-radius: 0 0 24px 24px; | |
box-shadow: 0 4px 6px rgba(32, 33, 36, 0.28); | |
display: none; | |
position: absolute; | |
background: white; | |
z-index: 1000; | |
} | |
#suggestions ul { | |
list-style-type: none; | |
padding: 0; | |
margin: 0; | |
} | |
#suggestions li { | |
padding: 10px 15px; | |
cursor: pointer; | |
border-bottom: 1px solid #eee; /* Subtle separator */ | |
} | |
#suggestions li:hover { | |
background-color: #f1f3f4; | |
} | |
#results { | |
width: 100%; | |
max-width: 700px; | |
padding: 20px 0; | |
} | |
.result { | |
margin-bottom: 20px; | |
padding: 15px; | |
border-radius: 8px; | |
background: #fff; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
} | |
.result h3 { | |
margin: 0; | |
font-weight: normal; | |
} | |
.result h3 a { | |
color: #1a0dab; | |
text-decoration: none; | |
font-size: 18px; | |
} | |
.result h3 a:hover { | |
text-decoration: underline; | |
} | |
.result .url { | |
color: #006621; | |
font-size: 14px; | |
margin-bottom: 3px; | |
} | |
.result p { | |
color: #545454; | |
font-size: 14px; | |
line-height: 1.58; | |
margin: 0; | |
} | |
.settings-icon { | |
background: none; | |
border: none; | |
cursor: pointer; | |
padding: 0; | |
position: absolute; | |
right: 5vw; | |
} | |
.settings-icon svg { | |
width: 24px; /* Increased icon size */ | |
height: 24px; | |
fill: #333; /* Darker icon color */ | |
} | |
.settings-menu { | |
display: none; | |
position: fixed; | |
top: 60px; | |
right: 20px; | |
background: #fff; | |
border: 1px solid #dfe1e5; | |
border-radius: 4px; | |
box-shadow: 0 4px 6px rgba(32, 33, 36, 0.28); | |
padding: 15px; | |
z-index: 1001; | |
width: 300px; /* Increased width for better visibility */ | |
} | |
.settings-menu select { | |
display: block; | |
margin-bottom: 10px; | |
padding: 8px 12px; | |
border-radius: 4px; | |
border: 1.6px solid #2b14fa; | |
appearance: none; | |
background: #ffffff | |
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M4 7l6 6 6-6z'></path></svg>") | |
no-repeat right 10px center; | |
font-size: 14px; | |
} | |
.settings-menu select:focus { | |
outline: none; | |
box-shadow: 0 0 0 5px #4285f4; | |
} | |
.settings-menu h4 { | |
margin-top: 0; | |
font-weight: bold; | |
color: #333; | |
} | |
/* About Section Styling */ | |
.about-section { | |
width: 100%; | |
max-width: 700px; | |
padding: 20px; | |
border-radius: 8px; | |
background: #fff; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
margin-top: 20px; | |
} | |
.about-section h2 { | |
color: #333; | |
margin-bottom: 10px; | |
} | |
.about-section p { | |
color: #545454; | |
font-size: 14px; | |
line-height: 1.58; | |
margin: 0; | |
} | |
/* People Also Search For Styling */ | |
.people-also-search { | |
width: 100%; | |
max-width: 700px; | |
padding: 20px; | |
border-radius: 8px; | |
background: #fff; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
margin-top: 20px; | |
} | |
.people-also-search h3 { | |
color: #333; | |
margin-bottom: 10px; | |
} | |
.people-also-search ul { | |
list-style: none; | |
padding: 0; | |
margin: 0; | |
} | |
.people-also-search li { | |
padding: 5px 0; | |
cursor: pointer; | |
color: #545454; | |
font-size: 14px; | |
} | |
.people-also-search li a { | |
text-decoration: none; | |
color: #1a0dab; | |
} | |
.people-also-search li a:hover { | |
text-decoration: underline; | |
} | |
.sidebar { | |
width: 300px; /* Adjust width as needed */ | |
padding: 20px; | |
background: #fff; | |
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | |
position: fixed; | |
top: 60px; | |
right: 20px; | |
height: calc(100vh - 60px); /* Adjust height as needed */ | |
overflow-y: auto; | |
display: none; | |
} | |
.sidebar h2, | |
.sidebar h3 { | |
color: #333; | |
margin-bottom: 10px; | |
} | |
.sidebar p { | |
color: #545454; | |
font-size: 14px; | |
line-height: 1.58; | |
margin: 0; | |
} | |
.sidebar ul { | |
list-style: none; | |
padding: 0; | |
margin: 0; | |
} | |
.sidebar li { | |
padding: 5px 0; | |
cursor: pointer; | |
color: #545454; | |
font-size: 14px; | |
} | |
.sidebar li a { | |
text-decoration: none; | |
color: #1a0dab; | |
} | |
.sidebar li a:hover { | |
text-decoration: underline; | |
} | |
.main-content { | |
margin-right: 320px; /* Adjust based on sidebar width */ | |
transition: margin-left 0.3s; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<header> | |
<div class="logo"> | |
<span>H</span><span>e</span><span>l</span><span>p</span><span>i</span | |
><span>ng</span><span>AI</span> | |
</div> | |
<button class="settings-icon" onclick="toggleSettings()"> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
width="24" | |
height="24" | |
viewBox="0 0 24 24" | |
fill="none" | |
stroke="currentColor" | |
stroke-width="2" | |
stroke-linecap="round" | |
stroke-linejoin="round" | |
class="feather feather-settings" | |
> | |
<circle cx="12" cy="12" r="3"></circle> | |
<path | |
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" | |
></path> | |
</svg> | |
</button> | |
<div class="settings-menu" id="settings-menu"> | |
<h4>Time Limit</h4> | |
<select id="timelimit"> | |
<option value="none">All Time</option> | |
<option value="d">Day</option> | |
<option value="w">Week</option> | |
<option value="m">Month</option> | |
<option value="y">Year</option> | |
</select> | |
<h4>Safe Search</h4> | |
<select id="safesearch"> | |
<option value="off">Off</option> | |
<option value="moderate">Moderate</option> | |
<option value="on">On</option> | |
</select> | |
</div> | |
</header> | |
<div class="sidebar" id="sidebar"> | |
<div id="about-section" style="display: none"> | |
<h2>About</h2> | |
<p id="about-description"></p> | |
</div> | |
<div id="people-also-search-section" style="display: none"> | |
<h3>People Also Search For</h3> | |
<ul id="people-also-search-list"></ul> | |
</div> | |
</div> | |
<div class="main-content"> | |
<div class="search-container"> | |
<form id="search-form"> | |
<div class="search-box"> | |
<input | |
type="text" | |
id="search-query" | |
placeholder="Search the web" | |
autocomplete="off" | |
/> | |
<button type="submit"> | |
<svg | |
focusable="false" | |
xmlns="http://www.w3.org/2000/svg" | |
viewBox="0 0 24 24" | |
width="24px" | |
> | |
<path | |
d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" | |
></path> | |
</svg> | |
</button> | |
</div> | |
</form> | |
<div id="suggestions"></div> | |
</div> | |
<div id="results"></div> | |
</div> | |
</div> | |
<script> | |
const searchForm = document.getElementById("search-form"); | |
const searchQueryInput = document.getElementById("search-query"); | |
const timelimitSelect = document.getElementById("timelimit"); | |
const safesearchSelect = document.getElementById("safesearch"); | |
const resultsContainer = document.getElementById("results"); | |
const suggestionsContainer = document.getElementById("suggestions"); | |
const peopleAlsoSearchList = document.getElementById( | |
"people-also-search-list" | |
); | |
const peopleAlsoSearchSection = document.getElementById( | |
"people-also-search-section" | |
); | |
const aboutSection = document.getElementById("about-section"); | |
const sidebar = document.getElementById("sidebar"); | |
const BASE_URL = "https://oevortex-webscout-api.hf.space"; | |
searchQueryInput.addEventListener("input", async () => { | |
const searchQuery = searchQueryInput.value; | |
const apiEndpoint = `${BASE_URL}/api/suggestions`; | |
if (searchQuery.trim() === "") { | |
suggestionsContainer.style.display = "none"; | |
return; | |
} | |
try { | |
const response = await fetch( | |
`${apiEndpoint}?q=${encodeURIComponent(searchQuery)}` | |
); | |
if (!response.ok) { | |
throw new Error( | |
`API request failed with status: ${response.status}` | |
); | |
} | |
const data = await response.json(); | |
displaySuggestions(data); | |
} catch (error) { | |
console.error("Error:", error); | |
suggestionsContainer.style.display = "none"; | |
} | |
}); | |
searchQueryInput.addEventListener("focus", () => { | |
if (searchQueryInput.value.trim() !== "") { | |
suggestionsContainer.style.display = "block"; | |
} | |
}); | |
document.addEventListener("click", (event) => { | |
if (!searchForm.contains(event.target)) { | |
suggestionsContainer.style.display = "none"; | |
} | |
}); | |
searchForm.addEventListener("submit", async (event) => { | |
event.preventDefault(); | |
const searchQuery = searchQueryInput.value; | |
const timelimit = timelimitSelect.value; | |
const safesearch = safesearchSelect.value; | |
await performSearch(searchQuery, timelimit, safesearch); | |
}); | |
function displaySuggestions(suggestions) { | |
suggestionsContainer.innerHTML = ""; | |
if (suggestions.length === 0) { | |
suggestionsContainer.style.display = "none"; | |
return; | |
} | |
const suggestionList = document.createElement("ul"); | |
suggestions.forEach((suggestion) => { | |
const listItem = document.createElement("li"); | |
listItem.textContent = suggestion.phrase; | |
listItem.addEventListener("click", () => { | |
searchQueryInput.value = suggestion.phrase; | |
suggestionsContainer.style.display = "none"; | |
performSearch(suggestion.phrase); | |
}); | |
suggestionList.appendChild(listItem); | |
}); | |
suggestionsContainer.appendChild(suggestionList); | |
suggestionsContainer.style.display = "block"; | |
} | |
async function performSearch(query, timelimit, safesearch) { | |
const apiEndpoint = `${BASE_URL}/api/search`; | |
try { | |
const response = await fetch( | |
`${apiEndpoint}?q=${encodeURIComponent( | |
query | |
)}&max_results=100&timelimit=${timelimit}&safesearch=${safesearch}` | |
); | |
if (!response.ok) { | |
throw new Error( | |
`API request failed with status: ${response.status}` | |
); | |
} | |
const searchResults = await response.json(); | |
displayResults(searchResults); | |
suggestionsContainer.style.display = "none"; | |
// Get "People Also Search For" data | |
const peopleAlsoSearchData = await getPeopleAlsoSearch(query); | |
// Display "About" section | |
const aboutDescription = peopleAlsoSearchData.find( | |
(item) => item.topic === null | |
); | |
if (aboutDescription) { | |
document.getElementById("about-description").textContent = | |
aboutDescription.text; | |
aboutSection.style.display = "block"; | |
} else { | |
aboutSection.style.display = "none"; | |
} | |
// Display "People Also Search For" list (limited to 5-6 items) | |
const peopleAlsoSearchItems = peopleAlsoSearchData.filter( | |
(item) => item.topic === "See also" | |
); | |
displayPeopleAlsoSearch(peopleAlsoSearchItems.slice(0, 6)); | |
if (peopleAlsoSearchItems.length > 0) { | |
peopleAlsoSearchSection.style.display = "block"; | |
} else { | |
peopleAlsoSearchSection.style.display = "none"; | |
} | |
if (aboutSection.style.display === "block" || peopleAlsoSearchSection.style.display === "block") { | |
// Show the sidebar if either section is displayed | |
sidebar.style.display = "block"; | |
document.querySelector(".main-content").style.marginLeft = "320px"; | |
} else { | |
// Hide the sidebar if both sections are hidden | |
sidebar.style.display = "none"; | |
document.querySelector(".main-content").style.marginLeft = "0px"; | |
} | |
} catch (error) { | |
console.error("Error:", error); | |
displayError("An error occurred while fetching results."); | |
} | |
} | |
async function getPeopleAlsoSearch(query) { | |
const apiEndpoint = `${BASE_URL}/api/answers`; | |
try { | |
const response = await fetch( | |
`${apiEndpoint}?q=${encodeURIComponent(query)}` | |
); | |
if (!response.ok) { | |
throw new Error( | |
`API request failed with status: ${response.status}` | |
); | |
} | |
const data = await response.json(); | |
return data; // Return the data from the API | |
} catch (error) { | |
console.error("Error:", error); | |
return null; // Return null if there's an error fetching data | |
} | |
} | |
function displayPeopleAlsoSearch(data) { | |
peopleAlsoSearchList.innerHTML = ""; // Clear previous list | |
if (data.length === 0) { | |
// Handle the case where no "People Also Search For" results are found | |
return; | |
} | |
data.forEach((item) => { | |
const listItem = document.createElement("li"); | |
const link = document.createElement("a"); | |
link.href = item.url; | |
link.textContent = item.text; | |
link.target = "_blank"; | |
link.rel = "noopener noreferrer"; | |
listItem.appendChild(link); | |
peopleAlsoSearchList.appendChild(listItem); | |
}); | |
} | |
function displayResults(results) { | |
resultsContainer.innerHTML = ""; | |
if (results.length === 0) { | |
displayError("No results found."); | |
return; | |
} | |
results.forEach((result) => { | |
const resultElement = document.createElement("div"); | |
resultElement.classList.add("result"); | |
const titleElement = document.createElement("h3"); | |
const titleLink = document.createElement("a"); | |
titleLink.href = result.href; | |
titleLink.textContent = result.title; | |
titleLink.target = "_blank"; | |
titleLink.rel = "noopener noreferrer"; | |
titleElement.appendChild(titleLink); | |
const urlElement = document.createElement("div"); | |
urlElement.classList.add("url"); | |
urlElement.textContent = result.href; | |
// Correctly using result.description now | |
const descriptionElement = document.createElement("p"); | |
descriptionElement.textContent = result.body; | |
resultElement.appendChild(titleElement); | |
resultElement.appendChild(urlElement); | |
resultElement.appendChild(descriptionElement); | |
resultsContainer.appendChild(resultElement); | |
}); | |
} | |
function displayError(message) { | |
resultsContainer.innerHTML = ""; | |
const errorElement = document.createElement("p"); | |
errorElement.textContent = message; | |
errorElement.style.color = "red"; | |
resultsContainer.appendChild(errorElement); | |
} | |
function toggleSettings() { | |
const settingsMenu = document.getElementById("settings-menu"); | |
settingsMenu.style.display = | |
settingsMenu.style.display === "block" ? "none" : "block"; | |
} | |
</script> | |
</body> | |
</html> |