Skip to content

Commit 42cdd58

Browse files
Merge pull request #94 from Josetic224/main
Implement Advanced Search System
2 parents b5843e8 + 30d09fa commit 42cdd58

7 files changed

Lines changed: 1100 additions & 0 deletions

File tree

src/app/search/page.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { AdvancedSearchInterface } from '@/components/search/AdvancedSearchInterface';
2+
3+
export const metadata = {
4+
title: 'Advanced Search | TeachLink',
5+
description: 'Powerful multi-dimensional search for the TeachLink ecosystem.',
6+
};
7+
8+
export default function SearchPage() {
9+
return (
10+
<main className="min-h-screen bg-slate-50/50">
11+
<AdvancedSearchInterface />
12+
</main>
13+
);
14+
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
'use client';
2+
3+
import React, { useState } from 'react';
4+
import {
5+
Search,
6+
Filter,
7+
Settings,
8+
Sparkles,
9+
ArrowLeft,
10+
X,
11+
History,
12+
TrendingUp,
13+
BrainCircuit
14+
} from 'lucide-react';
15+
import { useAdvancedSearch } from '../../hooks/useAdvancedSearch';
16+
import { IntelligentAutoComplete } from './IntelligentAutoComplete';
17+
import { FacetedFilterSystem } from './FacetedFilterSystem';
18+
import { SearchResultsVisualizer } from './SearchResultsVisualizer';
19+
20+
export const AdvancedSearchInterface: React.FC = () => {
21+
const {
22+
query,
23+
updateSearchText,
24+
updateFilters,
25+
updateSort,
26+
performSearch,
27+
clearFilters,
28+
results,
29+
isSearching,
30+
history,
31+
} = useAdvancedSearch();
32+
33+
const [showFilters, setShowFilters] = useState(false);
34+
const [hasSearched, setHasSearched] = useState(false);
35+
36+
const handleSearch = (text: string) => {
37+
updateSearchText(text);
38+
performSearch();
39+
setHasSearched(true);
40+
};
41+
42+
const handleReset = () => {
43+
clearFilters();
44+
updateSearchText('');
45+
setHasSearched(false);
46+
};
47+
48+
return (
49+
<div className="max-w-6xl mx-auto px-4 py-12 space-y-12">
50+
{/* Search Header Section */}
51+
<div className="text-center space-y-4 animate-in fade-in slide-in-from-top-4 duration-700">
52+
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-primary font-mono text-xs font-bold uppercase tracking-widest mb-2">
53+
<BrainCircuit className="w-3.5 h-3.5" /> AI-Powered Discovery
54+
</div>
55+
<h1 className="text-4xl md:text-6xl font-black font-sans text-slate-800 tracking-tight">
56+
Find <span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-accent">Expertise</span> Faster.
57+
</h1>
58+
<p className="text-slate-500 max-w-2xl mx-auto text-lg">
59+
Search across the entire Starknet knowledge ecosystem with multi-dimensional filters and intelligent suggestions.
60+
</p>
61+
</div>
62+
63+
{/* Main Search Bar Container */}
64+
<div className="max-w-3xl mx-auto space-y-6">
65+
<div className="flex flex-col sm:flex-row gap-3">
66+
<div className="flex-1">
67+
<IntelligentAutoComplete
68+
value={query.text}
69+
onChange={updateSearchText}
70+
onSearch={handleSearch}
71+
history={history}
72+
/>
73+
</div>
74+
<button
75+
onClick={() => setShowFilters(!showFilters)}
76+
className={`flex items-center justify-center gap-2 px-6 py-4 rounded-2xl font-mono text-xs uppercase tracking-widest font-bold transition-all h-[56px] border ${showFilters
77+
? 'bg-primary text-white border-primary shadow-lg shadow-primary/20'
78+
: 'bg-white text-slate-600 border-slate-200 hover:border-primary hover:text-primary'
79+
}`}
80+
>
81+
<Filter className={`w-4 h-4 ${showFilters ? 'rotate-180' : ''} transition-transform duration-300`} />
82+
{showFilters ? 'HIDE_FILTERS' : 'FILTERS'}
83+
</button>
84+
</div>
85+
86+
{/* Quick Insights / Trending Tags */}
87+
{!hasSearched && !showFilters && (
88+
<div className="flex flex-wrap items-center justify-center gap-4 text-slate-400 animate-in fade-in slide-in-from-bottom-2 delay-300 duration-700">
89+
<span className="flex items-center gap-1.5 text-[10px] font-mono font-bold uppercase tracking-widest">
90+
<TrendingUp className="w-3 h-3" /> Trending:
91+
</span>
92+
{['#Cairo1.0', '#StarknetOS', '#ZeroKnowledge', '#L2Scalability'].map(tag => (
93+
<button
94+
key={tag}
95+
onClick={() => handleSearch(tag)}
96+
className="text-xs font-medium px-3 py-1 rounded-full bg-slate-50 border border-slate-100 hover:border-primary/30 hover:text-primary transition-all active:scale-95"
97+
>
98+
{tag}
99+
</button>
100+
))}
101+
</div>
102+
)}
103+
</div>
104+
105+
{/* Interface Body */}
106+
<div className="grid grid-cols-1 gap-12">
107+
{/* Filters Panel (Collapsible) */}
108+
{showFilters && (
109+
<div className="animate-in fade-in zoom-in-95 duration-500">
110+
<FacetedFilterSystem
111+
filters={query.filters}
112+
onFilterChange={updateFilters}
113+
onReset={clearFilters}
114+
/>
115+
</div>
116+
)}
117+
118+
{/* Results Section */}
119+
<div className={`space-y-8 ${isSearching ? 'opacity-70' : ''} transition-opacity`}>
120+
{hasSearched ? (
121+
<SearchResultsVisualizer
122+
results={results}
123+
isSearching={isSearching}
124+
sortBy={query.sortBy}
125+
onSortChange={updateSort}
126+
/>
127+
) : (
128+
<div className="py-20 text-center space-y-8 max-w-lg mx-auto">
129+
<div className="relative inline-block">
130+
<div className="absolute inset-0 bg-primary/20 blur-3xl rounded-full scale-150 animate-pulse"></div>
131+
<div className="relative glass-panel w-24 h-24 rounded-3xl flex items-center justify-center text-primary mb-6 mx-auto rotate-12 hover:rotate-0 transition-transform duration-500">
132+
<Sparkles className="w-10 h-10" />
133+
</div>
134+
</div>
135+
<div className="space-y-2">
136+
<h3 className="text-2xl font-bold font-sans text-slate-800 tracking-tight">Ready to explore?</h3>
137+
<p className="text-slate-500">
138+
Discover a curated collection of decentralized knowledge, from beginners tutorials to advanced cryptographic research.
139+
</p>
140+
</div>
141+
<div className="grid grid-cols-2 gap-4">
142+
<div className="glass-panel p-4 rounded-2xl border-slate-100 text-left space-y-2 hover:border-primary/20 transition-colors group cursor-pointer">
143+
<div className="w-8 h-8 rounded-lg bg-blue-50 flex items-center justify-center text-blue-500 group-hover:bg-primary group-hover:text-white transition-colors">
144+
<BrainCircuit className="w-4 h-4" />
145+
</div>
146+
<h4 className="text-sm font-bold font-sans">Learn Cairo</h4>
147+
<p className="text-[11px] text-slate-400">Master the native language of Starknet.</p>
148+
</div>
149+
<div className="glass-panel p-4 rounded-2xl border-slate-100 text-left space-y-2 hover:border-secondary transition-colors group cursor-pointer">
150+
<div className="w-8 h-8 rounded-lg bg-emerald-50 flex items-center justify-center text-emerald-500 group-hover:bg-accent group-hover:text-white transition-colors">
151+
<Filter className="w-4 h-4" />
152+
</div>
153+
<h4 className="text-sm font-bold font-sans">Find Topics</h4>
154+
<p className="text-[11px] text-slate-400">Explore categorized knowledge bases.</p>
155+
</div>
156+
</div>
157+
</div>
158+
)}
159+
</div>
160+
</div>
161+
162+
{/* Search Insights Tooltip (Utility) */}
163+
<div className="fixed bottom-8 left-8">
164+
<div className="relative group">
165+
<button className="w-12 h-12 bg-white border border-slate-200 rounded-2xl flex items-center justify-center text-slate-400 hover:text-primary hover:border-primary transition-all shadow-xl shadow-slate-200/50 hover:shadow-primary/20 hover:scale-110 active:scale-95">
166+
<History className="w-5 h-5" />
167+
</button>
168+
<div className="absolute bottom-full left-0 mb-4 w-64 bg-white rounded-2xl shadow-2xl border border-slate-100 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300 translate-y-2 group-hover:translate-y-0 p-4">
169+
<h4 className="text-[10px] font-mono font-bold uppercase tracking-widest text-slate-400 mb-3 flex items-center gap-2">
170+
<History className="w-3 h-3" /> Recent History
171+
</h4>
172+
<div className="space-y-2">
173+
{history.length > 0 ? (
174+
history.slice(0, 5).map((term, i) => (
175+
<button
176+
key={i}
177+
onClick={() => handleSearch(term)}
178+
className="w-full text-left p-2 rounded-lg hover:bg-slate-50 text-xs text-slate-600 truncate flex items-center gap-2"
179+
>
180+
<div className="w-1 h-1 bg-slate-300 rounded-full"></div>
181+
{term}
182+
</button>
183+
))
184+
) : (
185+
<p className="text-[10px] text-slate-300 italic">No recent searches</p>
186+
)}
187+
</div>
188+
</div>
189+
</div>
190+
</div>
191+
</div>
192+
);
193+
};
194+
195+
export default AdvancedSearchInterface;

0 commit comments

Comments
 (0)