khronoz commited on
Commit
35dd4ef
·
1 Parent(s): 5bf97a0

Vector Search UI & Skeletal Code to send request to backend

Browse files
frontend/app/components/search-section.tsx ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // SearchSection.tsx
2
+
3
+ import React, { useState, ChangeEvent, FormEvent } from "react";
4
+ import useSearch from "@/app/components/ui/search/useSearch";
5
+ import SearchResults from "@/app/components/ui/search/search-results";
6
+ import SearchInput from "@/app/components/ui/search/search-input";
7
+
8
+ const SearchSection: React.FC = () => {
9
+ const [query, setQuery] = useState("");
10
+ const { searchResults, isLoading, handleSearch } = useSearch();
11
+
12
+ const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
13
+ setQuery(e.target.value);
14
+ };
15
+
16
+ const handleSearchSubmit = (e: FormEvent) => {
17
+ e.preventDefault();
18
+ handleSearch(query);
19
+ };
20
+
21
+ return (
22
+ <div className="space-y-4 max-w-5xl w-full">
23
+ <SearchInput
24
+ query={query}
25
+ isLoading={isLoading}
26
+ onInputChange={handleInputChange}
27
+ onSearchSubmit={handleSearchSubmit}
28
+ />
29
+ <SearchResults results={searchResults} isLoading={isLoading} />
30
+ </div>
31
+ );
32
+ };
33
+
34
+ export default SearchSection;
frontend/app/components/ui/search/search-input.tsx ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // SearchInput.tsx
2
+
3
+ import React, { ChangeEvent, FormEvent } from "react";
4
+ import { Button } from "../button";
5
+ import { Input } from "../input";
6
+ import { Search } from "lucide-react";
7
+
8
+ interface SearchInputProps {
9
+ query: string;
10
+ isLoading: boolean;
11
+ onInputChange: (e: ChangeEvent<HTMLInputElement>) => void;
12
+ onSearchSubmit: (e: FormEvent) => void;
13
+ }
14
+
15
+ const SearchInput: React.FC<SearchInputProps> = ({
16
+ query,
17
+ isLoading,
18
+ onInputChange,
19
+ onSearchSubmit,
20
+ }) => {
21
+ return (
22
+ <form
23
+ onSubmit={onSearchSubmit}
24
+ className="flex w-full items-start justify-between gap-4 rounded-xl bg-white dark:bg-zinc-700/30 p-4 shadow-xl"
25
+ >
26
+ <Input
27
+ autoFocus
28
+ name="query"
29
+ placeholder="Enter a text to search..."
30
+ value={query}
31
+ onChange={onInputChange}
32
+ className="flex-1 bg-white dark:bg-zinc-500/30"
33
+ />
34
+ <Button type="submit" disabled={isLoading} className="hidden md:flex items-center transition duration-300 ease-in-out transform hover:scale-110">
35
+ Search
36
+ </Button>
37
+ <Button type="submit" disabled={isLoading} className="md:hidden"> {/* Hide on larger screens */}
38
+ <Search className="h-5 w-5" />
39
+ </Button>
40
+ </form>
41
+ );
42
+ };
43
+
44
+ export default SearchInput;
frontend/app/components/ui/search/search-results.tsx ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import { SearchResult } from "./search-types";
3
+ import { IconSpinner } from "../icons";
4
+
5
+ interface SearchResultsProps {
6
+ results: SearchResult[];
7
+ isLoading: boolean;
8
+ }
9
+
10
+ const SearchResults: React.FC<SearchResultsProps> = ({ results, isLoading }) => {
11
+ return (
12
+ <div className="flex w-full items-start justify-between gap-4 rounded-xl bg-white dark:bg-zinc-700/30 p-4 shadow-xl">
13
+ {isLoading ? (
14
+ <div className="flex items-center">
15
+ <IconSpinner className="mr-2 animate-spin" />
16
+ <p>Loading...</p>
17
+ </div>
18
+ ) : null}
19
+ {!isLoading && results.length === 0 && <p>No results found.</p>}
20
+ {!isLoading && results.length > 0 && (
21
+ <ul>
22
+ {results.map((result) => (
23
+ <li key={result.id}>{result.title}</li>
24
+ ))}
25
+ </ul>
26
+ )}
27
+ </div>
28
+ );
29
+ };
30
+
31
+ export default SearchResults;
frontend/app/components/ui/search/search-types.tsx ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ // SearchTypes.tsx
2
+ export interface SearchResult {
3
+ id: number;
4
+ title: string;
5
+ // Add more properties as needed
6
+ }
frontend/app/components/ui/search/useSearch.tsx ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from "react";
2
+
3
+ interface SearchResult {
4
+ id: number;
5
+ title: string;
6
+ // Add more properties as needed
7
+ }
8
+
9
+ interface UseSearchResult {
10
+ searchResults: SearchResult[];
11
+ isLoading: boolean;
12
+ handleSearch: (query: string) => Promise<void>;
13
+ }
14
+
15
+ const useSearch = (): UseSearchResult => {
16
+ const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
17
+ const [isLoading, setIsLoading] = useState(false);
18
+
19
+ const handleSearch = async (query: string): Promise<void> => {
20
+ setIsLoading(true);
21
+
22
+ // Perform your search logic here
23
+ // Replace the following with your actual search API or function
24
+ try {
25
+ const response = await fetch(`/api/search?query=${query}`);
26
+ const data = await response.json();
27
+ setSearchResults(data);
28
+ } catch (error) {
29
+ console.error("Error during search:", error);
30
+ setSearchResults([]);
31
+ }
32
+
33
+ setIsLoading(false);
34
+ };
35
+
36
+ useEffect(() => {
37
+ // Initial load logic if needed
38
+ // ...
39
+
40
+ // Cleanup logic if needed
41
+ return () => {
42
+ // ...
43
+ };
44
+ }, []); // Dependency array depends on your use case
45
+
46
+ return {
47
+ searchResults,
48
+ isLoading,
49
+ handleSearch,
50
+ };
51
+ };
52
+
53
+ export default useSearch;
frontend/app/search/page.tsx CHANGED
@@ -1,14 +1,14 @@
1
  "use client";
2
 
3
  import Header from "@/app/components/header";
4
- import ChatSection from "@/app/components/chat-section";
5
 
6
  export default function Search() {
7
 
8
  return (
9
  <main id='main-container' className="flex min-h-screen flex-col items-center gap-10 background-gradient dark:background-gradient-dark md:pt-10 pt-24 px-10">
10
  <Header />
11
- <ChatSection />
12
  </main>
13
  );
14
  }
 
1
  "use client";
2
 
3
  import Header from "@/app/components/header";
4
+ import SearchSection from "@/app/components/search-section";
5
 
6
  export default function Search() {
7
 
8
  return (
9
  <main id='main-container' className="flex min-h-screen flex-col items-center gap-10 background-gradient dark:background-gradient-dark md:pt-10 pt-24 px-10">
10
  <Header />
11
+ <SearchSection />
12
  </main>
13
  );
14
  }