1+ <script lang =" ts" >
2+ import type { Paper } from ' $lib/models/paper' ;
3+
4+ // Props with callbacks
5+ const {
6+ initialTitle = ' ' ,
7+ initialAuthor = ' ' ,
8+ initialOrder = ' citations_year' ,
9+ initialDirection = ' desc' ,
10+ onPapers = (papers : Paper [], count : number ) => {}
11+ } = $props ();
12+
13+ // State
14+ let title = $state (initialTitle );
15+ let author = $state (initialAuthor );
16+ let order = $state (initialOrder );
17+ let direction = $state (initialDirection );
18+ let isLoading = $state (false );
19+ let isExpanded = $state (false );
20+
21+ async function search() {
22+ isLoading = true ;
23+ const requestUrl = ` /api/paper/search/title?title=${encodeURIComponent (title )}&author=${encodeURIComponent (author )}&order=${encodeURIComponent (order )}&direction=${encodeURIComponent (direction )}&limit=10 ` ;
24+ console .log (requestUrl );
25+ const response = await fetch (requestUrl );
26+ const data = await response .json ();
27+ console .log (data );
28+
29+ // Call the callback with search results
30+ if (data .count && data .count > 0 ) {
31+ onPapers (data .paper , data .count );
32+ } else {
33+ onPapers ([], 0 );
34+ }
35+
36+ isLoading = false ;
37+ }
38+ </script >
39+
40+ <div class =" bg-white rounded-lg shadow-md" >
41+ <!-- Basic Search Header -->
42+ <div class =" w-full p-4 flex items-center justify-between" >
43+ <div class =" flex-1" >
44+ <input
45+ type =" text"
46+ name =" title"
47+ id =" title"
48+ class =" w-full text-lg rounded-md border-gray-300 focus:border-gray-500"
49+ bind:value ={title }
50+ oninput ={search }
51+ placeholder =" Search by title..."
52+ />
53+ </div >
54+ <div class =" flex items-center gap-4 ml-4" >
55+ {#if isLoading }
56+ <svg class =" animate-spin h-5 w-5 text-indigo-600" xmlns =" http://www.w3.org/2000/svg" fill =" none" viewBox =" 0 0 24 24" >
57+ <circle class =" opacity-25" cx =" 12" cy =" 12" r =" 10" stroke =" currentColor" stroke-width =" 4" ></circle >
58+ <path class =" opacity-75" fill =" currentColor" d =" M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" ></path >
59+ </svg >
60+ {/if }
61+ <button
62+ class =" p-2 hover:bg-gray-50 rounded-full transition-colors"
63+ onclick ={() => isExpanded = ! isExpanded }
64+ aria-label ={isExpanded ? " Collapse advanced search" : " Expand advanced search" }
65+ >
66+ <svg
67+ class ="w-6 h-6 text-gray-500 transform transition-transform {isExpanded ? ' rotate-180' : ' ' }"
68+ xmlns =" http://www.w3.org/2000/svg"
69+ viewBox =" 0 0 20 20"
70+ fill =" currentColor"
71+ >
72+ <path fill-rule =" evenodd" d =" M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule =" evenodd" />
73+ </svg >
74+ </button >
75+ </div >
76+ </div >
77+
78+ <!-- Advanced Search Content -->
79+ {#if isExpanded }
80+ <div class =" border-t border-gray-200 p-4" >
81+ <div class =" grid grid-cols-1 md:grid-cols-3 gap-4" >
82+ <div >
83+ <label for =" author" class =" block text-sm font-medium text-gray-700" >Author</label >
84+ <input
85+ type =" text"
86+ name =" author"
87+ id =" author"
88+ class =" mt-1 block w-full text-lg rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
89+ bind:value ={author }
90+ oninput ={search }
91+ />
92+ </div >
93+ <div >
94+ <label for =" order" class =" block text-sm font-medium text-gray-700" >Order by</label >
95+ <select
96+ name =" order"
97+ id =" order"
98+ class =" mt-1 block w-full text-lg rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
99+ bind:value ={order }
100+ onchange ={search }
101+ >
102+ <option value =" citations_year" >Citations per Year</option >
103+ <option value =" citations" >Total Citations</option >
104+ </select >
105+ </div >
106+ <div >
107+ <label for =" direction" class =" block text-sm font-medium text-gray-700" >Direction</label >
108+ <select
109+ name =" direction"
110+ id =" direction"
111+ class =" mt-1 block w-full text-lg rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
112+ bind:value ={direction }
113+ onchange ={search }
114+ >
115+ <option value =" desc" >Descending</option >
116+ <option value =" asc" >Ascending</option >
117+ </select >
118+ </div >
119+ </div >
120+ </div >
121+ {/if }
122+ </div >
0 commit comments