import { useState, useEffect, useRef } from 'react' import { useNavigate, Link } from 'react-router-dom' import { Search, Clock, ArrowRight, Play, Loader2, TrendingUp, Sparkles, Zap } from 'lucide-react' import { treesApi } from '@/api/trees' import { sessionsApi } from '@/api/sessions' import type { TreeListItem } from '@/types' import type { Session } from '@/types/session' import { cn } from '@/lib/utils' function timeAgo(dateStr: string): string { const now = Date.now() const then = new Date(dateStr).getTime() const diffMs = now - then const minutes = Math.floor(diffMs / 60000) if (minutes < 1) return 'just now' if (minutes < 60) return `${minutes}m ago` const hours = Math.floor(minutes / 60) if (hours < 24) return `${hours}h ago` const days = Math.floor(hours / 24) return `${days}d ago` } export function QuickStartPage() { const navigate = useNavigate() const [query, setQuery] = useState('') const [searchResults, setSearchResults] = useState([]) const [isSearching, setIsSearching] = useState(false) const [showResults, setShowResults] = useState(false) const [activeSessions, setActiveSessions] = useState([]) const [recentTrees, setRecentTrees] = useState<{ tree_id: string; name: string; lastUsed: string }[]>([]) const [isLoading, setIsLoading] = useState(true) const searchRef = useRef(null) const debounceRef = useRef | null>(null) // Load sessions on mount useEffect(() => { async function loadData() { try { const [active, recent] = await Promise.all([ sessionsApi.list({ completed: false, size: 5 }), sessionsApi.list({ size: 10 }), ]) setActiveSessions(active.slice(0, 3)) // Deduplicate recent sessions by tree_id, max 5 const seen = new Set() const deduped: { tree_id: string; name: string; lastUsed: string }[] = [] for (const s of recent) { if (!seen.has(s.tree_id) && deduped.length < 5) { seen.add(s.tree_id) deduped.push({ tree_id: s.tree_id, name: s.tree_snapshot?.name || 'Unnamed Tree', lastUsed: s.started_at, }) } } setRecentTrees(deduped) } catch (err) { console.error('Failed to load sessions:', err) } finally { setIsLoading(false) } } loadData() }, []) // Debounced search useEffect(() => { if (debounceRef.current) clearTimeout(debounceRef.current) if (query.length < 2) { setSearchResults([]) setShowResults(false) setIsSearching(false) return } setIsSearching(true) setShowResults(true) debounceRef.current = setTimeout(async () => { try { const results = await treesApi.search(query, 8) setSearchResults(results) } catch (err) { console.error('Search failed:', err) setSearchResults([]) } finally { setIsSearching(false) } }, 300) return () => { if (debounceRef.current) clearTimeout(debounceRef.current) } }, [query]) // Close dropdown on outside click useEffect(() => { function handleClick(e: MouseEvent) { if (searchRef.current && !searchRef.current.contains(e.target as Node)) { setShowResults(false) } } document.addEventListener('mousedown', handleClick) return () => document.removeEventListener('mousedown', handleClick) }, []) return (
{/* Animated background grid */}
{/* Hero Section */}
{/* Badge */}
AI-Powered Troubleshooting
{/* Title */}

What are you troubleshooting?

Search our library of proven decision trees or continue where you left off

{/* Enhanced Search Bar */}
{/* Glow effect */}
setQuery(e.target.value)} onFocus={() => query.length >= 2 && setShowResults(true)} placeholder="Paste ticket subject or search for a tree..." className={cn( 'w-full rounded-xl border border-slate-700/50 bg-slate-900/90 backdrop-blur-xl py-5 pl-14 pr-5 text-lg', 'text-white placeholder:text-slate-500', 'focus:outline-none focus:ring-2 focus:ring-violet-500/50 focus:border-violet-500/50', 'transition-all duration-300' )} /> {query && ( )}
{/* Enhanced Search Results Dropdown */} {showResults && (
{isSearching ? (
) : searchResults.length === 0 ? (
No results found
Try a different search term
) : (
    {searchResults.map((tree, idx) => (
  • ))}
)}
)}
{/* Continue Session Section */} {activeSessions.length > 0 && (

Continue Session

{activeSessions.map((session, idx) => ( ))}
)} {/* Recent Trees Section */} {!isLoading && recentTrees.length > 0 && (

Recent Trees

{recentTrees.map((tree, idx) => ( ))}
)} {/* Footer CTA */}
Browse All Trees
) } export default QuickStartPage