From 5adbfe14ab0acad38a4f8b14d33d260c7f5f9352 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Wed, 24 Jul 2024 17:43:19 +0530 Subject: [PATCH] Add a search page that just renders truncated results when you click search --- src/interface/web/app/search/layout.tsx | 24 +++ src/interface/web/app/search/page.tsx | 170 ++++++++++++++++++ .../web/app/search/search.module.css | 12 ++ 3 files changed, 206 insertions(+) create mode 100644 src/interface/web/app/search/layout.tsx create mode 100644 src/interface/web/app/search/page.tsx create mode 100644 src/interface/web/app/search/search.module.css diff --git a/src/interface/web/app/search/layout.tsx b/src/interface/web/app/search/layout.tsx new file mode 100644 index 00000000..ed06f884 --- /dev/null +++ b/src/interface/web/app/search/layout.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from "next"; + +import "../globals.css"; + + +export const metadata: Metadata = { + title: "Khoj AI - Search", + description: "Search through all the documents you've shared with Khoj AI using natural language queries.", + icons: { + icon: '/static/favicon.ico', + }, +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( +
+ {children} +
+ ); +} diff --git a/src/interface/web/app/search/page.tsx b/src/interface/web/app/search/page.tsx new file mode 100644 index 00000000..30be4f5d --- /dev/null +++ b/src/interface/web/app/search/page.tsx @@ -0,0 +1,170 @@ +'use client' + +import { Input } from '@/components/ui/input'; + +import { useAuthenticatedData } from '../common/auth'; +import { useEffect, useState } from 'react'; +import SidePanel from '../components/sidePanel/chatHistorySidePanel'; +import NavMenu from '../components/navMenu/navMenu'; +import styles from './search.module.css'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; +import { Folder, FolderOpen, GithubLogo, LinkSimple, MagnifyingGlass, NoteBlank, NotionLogo } from '@phosphor-icons/react'; + +interface AdditionalData { + file: string; + source: string; + compiled: string; + heading: string; +} + +interface SearchResult { + type: string; + additional: AdditionalData; + entry: string; + score: number; + "corpus-id": string; +} + +function getNoteTypeIcon(source: string) { + if (source === 'notion') { + return ; + } + if (source === 'github') { + return ; + } + return ; +} + +function Note(note: SearchResult) { + const isFileNameURL = (note.additional.file || '').startsWith('http'); + const fileName = isFileNameURL ? note.additional.heading : note.additional.file.split('/').pop(); + console.log("note.additional.file", note.additional.file); + console.log("filename", fileName); + return ( + + + +
+ {getNoteTypeIcon(note.additional.source)} +
+
+ + {fileName} + +
+ +
+ {note.entry} +
+
+ + { + isFileNameURL ? + + {note.additional.file} + + : +
+ {note.additional.file} +
+ } +
+
+ ); + +} + +export default function Search() { + const authenticatedData = useAuthenticatedData(); + const [searchQuery, setSearchQuery] = useState(''); + const [isMobileWidth, setIsMobileWidth] = useState(false); + const [title, setTitle] = useState('Search'); + const [searchResults, setSearchResults] = useState([]); + const [searchResultsLoading, setSearchResultsLoading] = useState(false); + + useEffect(() => { + setIsMobileWidth(window.innerWidth < 786); + + window.addEventListener('resize', () => { + setIsMobileWidth(window.innerWidth < 786); + }); + + }, []); + + useEffect(() => { + setTitle(isMobileWidth ? '' : 'Search'); + }, [isMobileWidth]); + + function search(query: string) { + if (searchResultsLoading) { + return; + } + + if (!searchQuery.trim()) { + return; + } + + const apiUrl = `/api/search?q=${encodeURIComponent(searchQuery)}&client=web`; + fetch(apiUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + } + }).then(response => response.json()) + .then(data => { + setSearchResults(data); + setSearchResultsLoading(false); + }).catch((error) => { + console.error('Error:', error); + }); + } + + console.log('searchResults', searchResults); + + return ( +
+
+ +
+
+ +
+ { + isMobileWidth &&
Search
+ } +
+ + setSearchQuery(e.target.value)} + type="search" + placeholder="Search Documents" /> + +
+ { + searchResults.length > 0 && +
+ + { + searchResults.map((result, index) => { + return ( + + ); + }) + } + +
+ } +
+
+
+ ); +} diff --git a/src/interface/web/app/search/search.module.css b/src/interface/web/app/search/search.module.css new file mode 100644 index 00000000..b063fde6 --- /dev/null +++ b/src/interface/web/app/search/search.module.css @@ -0,0 +1,12 @@ +div.searchLayout { + display: grid; + grid-template-columns: auto 1fr; + gap: 1rem; + height: 100vh; +} + +@media screen and (max-width: 768px) { + div.searchLayout { + gap: 0; + } +}