feature: search auto complete API

This commit is contained in:
Alikia2x 2024-04-10 00:11:08 +08:00
parent 8e65767ac1
commit 04d72d3ca8
7 changed files with 347 additions and 294 deletions

View File

@ -0,0 +1,13 @@
import { completeGoogle } from "search-engine-autocomplete";
import { NextRequest } from "next/server"
export async function GET(request: NextRequest) {
const query = request.nextUrl.searchParams.get('q')!;
let language = request.nextUrl.searchParams.get('l');
if (language === null) language = 'en-US';
const data = await completeGoogle(query, language);
const completeWord: string | undefined = data.suggestions.filter((s) => {
return s.relativeRelevance > 0.96
})[0]?.suggestion;
return new Response(completeWord ? completeWord : query);
}

View File

@ -0,0 +1,9 @@
import { completeGoogle } from "search-engine-autocomplete";
import { NextRequest } from "next/server"
export async function GET(request: NextRequest) {
const query = request.nextUrl.searchParams.get('q')!;
const language = "ja-JP";
const data = await completeGoogle(query, language);
return new Response(JSON.stringify(data));
}

View File

@ -1,16 +1,24 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import SuggestionBox from "./suggestionBox";
import Suggestion from "./suggestion";
import { useRecoilValue } from "recoil";
import { queryState } from "@/components/state/query";
export default function(){
export default function () {
const [suggestion, setSuggetsion] = useState([]);
const query = useRecoilValue(queryState);
useEffect(() => {
fetch(`/api/suggestion?q=${query}`)
.then((res) => res.json())
.then((data) => {
setSuggetsion(data);
});
}, [query]);
return (
<SuggestionBox>
{
suggestion.map((s: string) => {
return <Suggestion key={s}>{s}</Suggestion>
})
}
{suggestion.map((s: string) => {
return <Suggestion key={s}>{s}</Suggestion>;
})}
</SuggestionBox>
)
);
}

View File

@ -1,16 +1,17 @@
"use client";
import { useRecoilValue } from "recoil";
import { useRecoilState, useRecoilValue } from "recoil";
import { settingsState } from "../state/settings";
import { useTranslations } from "next-intl";
import { useState } from "react";
import { normalizeURL } from "@/lib/normalizeURL";
import validLink from "@/lib/url/validLink";
import { queryState } from "../state/query";
export default function Search(props: { onFocus: () => void }) {
const settings: settings = useRecoilValue(settingsState);
const t = useTranslations("Search");
const [query, setQuery] = useState("");
const [query, setQuery] = useRecoilState(queryState);
let style = "default";
@ -41,7 +42,11 @@ export default function Search(props: { onFocus: () => void }) {
placeholder={t("placeholder")}
onFocus={props.onFocus}
onKeyDown={handleKeydown}
onChange={(e) => setQuery(e.target.value)}
onChange={(e) =>
setQuery((_) => {
return e.target.value;
})
}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"

10
components/state/query.ts Normal file
View File

@ -0,0 +1,10 @@
import { atom } from "recoil";
const queryState = atom({
key: "searchQuery",
default: ""
});
export {
queryState,
}

View File

@ -1,6 +1,6 @@
{
"name": "sparkhome",
"version": "4.2.0",
"version": "4.10.0",
"private": false,
"scripts": {
"dev": "next dev",
@ -12,14 +12,15 @@
"dependencies": {
"@nextui-org/react": "^2.2.10",
"clsx": "^2.1.0",
"framer-motion": "^11.0.24",
"framer-motion": "^11.0.25",
"next": "14.1.4",
"next-intl": "^3.10.0",
"next-intl": "^3.11.1",
"next-themes": "^0.3.0",
"punycode": "^2.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"recoil": "^0.7.7",
"search-engine-autocomplete": "^0.4.2",
"tailwind-merge": "^2.2.2",
"ts-node": "^10.9.2",
"valid-url": "^1.0.9",
@ -28,19 +29,19 @@
"devDependencies": {
"@jest/globals": "^29.7.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.2",
"@testing-library/react": "^14.3.0",
"@types/jest": "^29.5.12",
"@types/node": "^20",
"@types/node": "^20.12.6",
"@types/punycode": "^2.1.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react": "^18.2.75",
"@types/react-dom": "^18.2.24",
"@types/valid-url": "^1.0.7",
"autoprefixer": "^10.0.1",
"autoprefixer": "^10.4.19",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"ts-jest": "^29.1.2",
"typescript": "^5"
"typescript": "^5.4.4"
}
}

File diff suppressed because it is too large Load Diff