From 60d49272bffffc48af668a6472466fa059cfc3d1 Mon Sep 17 00:00:00 2001 From: Yves Gugger Date: Thu, 11 Dec 2025 07:41:10 +0100 Subject: [PATCH] feat: RADAR & MARKET - Content Integration & Award-Winning Search Changes: - TerminalLayout: - Added 'hideHeaderSearch' prop to remove top bar elements - Header is now non-sticky and transparent when search is hidden for seamless integration - RADAR (Dashboard): - Removed top bar search/shortcuts - Implemented 'Hero Style' Universal Search: - Floating design with backdrop blur - Dynamic emerald glow on focus - Animated icons and clean typography - Integrated results dropdown - Content flows seamlessly from top - MARKET: - Integrated header into content (removed sticky behavior) - Removed duplicate search/shortcuts from top bar --- frontend/src/app/terminal/market/page.tsx | 6 +- frontend/src/app/terminal/radar/page.tsx | 183 +++++++++++------- frontend/src/components/TerminalLayout.tsx | 212 +++++++++++---------- 3 files changed, 232 insertions(+), 169 deletions(-) diff --git a/frontend/src/app/terminal/market/page.tsx b/frontend/src/app/terminal/market/page.tsx index 3d59ca4..2ba5903 100644 --- a/frontend/src/app/terminal/market/page.tsx +++ b/frontend/src/app/terminal/market/page.tsx @@ -403,7 +403,11 @@ export default function MarketPage() { const formatPrice = (price: number) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(price) return ( - +
{/* Page-specific emerald glow (mirrors landing page look) */}
diff --git a/frontend/src/app/terminal/radar/page.tsx b/frontend/src/app/terminal/radar/page.tsx index d6ffa4d..39e093c 100644 --- a/frontend/src/app/terminal/radar/page.tsx +++ b/frontend/src/app/terminal/radar/page.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useState, useMemo, useCallback } from 'react' +import { useEffect, useState, useMemo, useCallback, useRef } from 'react' import { useSearchParams } from 'next/navigation' import { useStore } from '@/lib/store' import { api } from '@/lib/api' @@ -28,13 +28,14 @@ import { Loader2, Wifi, ShieldAlert, - BarChart3 + BarChart3, + Command } from 'lucide-react' import clsx from 'clsx' import Link from 'next/link' // ============================================================================ -// SHARED COMPONENTS (Matching Market Page Style) +// SHARED COMPONENTS // ============================================================================ function Tooltip({ children, content }: { children: React.ReactNode; content: string }) { @@ -136,6 +137,8 @@ export default function RadarPage() { const [searchQuery, setSearchQuery] = useState('') const [searchResult, setSearchResult] = useState(null) const [addingToWatchlist, setAddingToWatchlist] = useState(false) + const [searchFocused, setSearchFocused] = useState(false) + const searchInputRef = useRef(null) // Load Data const loadDashboardData = useCallback(async () => { @@ -220,6 +223,18 @@ export default function RadarPage() { return () => clearTimeout(timer) }, [searchQuery, handleSearch]) + // Focus shortcut + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.metaKey && e.key === 'k') { + e.preventDefault() + searchInputRef.current?.focus() + } + } + window.addEventListener('keydown', handleKeyDown) + return () => window.removeEventListener('keydown', handleKeyDown) + }, []) + // Computed const { availableDomains, totalDomains, greeting, subtitle } = useMemo(() => { const available = domains?.filter(d => d.is_available) || [] @@ -241,6 +256,7 @@ export default function RadarPage() { {toast && } @@ -260,7 +276,7 @@ export default function RadarPage() { {/* 2. STAT GRID */}
- + - +
- {/* 3. UNIVERSAL SEARCH */} -
-
-
- -
-

Universal Domain Search

-

Check availability, auctions & marketplace instantly

-
+ {/* 3. AWARD-WINNING SEARCH (HERO STYLE) */} +
+
+
+
+ + setSearchQuery(e.target.value)} + onFocus={() => setSearchFocused(true)} + onBlur={() => setSearchFocused(false)} + placeholder="Analyze any domain..." + className="w-full bg-transparent text-xl sm:text-2xl text-white placeholder:text-zinc-600 font-light outline-none" + /> + {!searchQuery && ( +
+ K +
+ )} + {searchQuery && ( + + )} +
-
- - setSearchQuery(e.target.value)} - placeholder="Enter domain (e.g. pounce.com)" - className="w-full h-14 pl-12 pr-4 bg-zinc-900/50 border border-white/10 rounded-xl - text-lg text-white placeholder:text-zinc-600 - focus:outline-none focus:border-emerald-500/50 focus:ring-1 focus:ring-emerald-500/50 transition-all shadow-inner" - /> -
- - {/* Search Results Panel */} - {searchResult && ( -
-
+ {/* SEARCH RESULTS DROPDOWN */} + {searchResult && ( +
{searchResult.loading ? ( -
+
- Analyzing global databases... + Scanning global availability...
) : ( -
- {/* Availability Status */} -
-
- {searchResult.available === true ? ( -
+
+ {/* Availability Card */} +
+
+ {searchResult.available ? ( +
- ) : searchResult.available === false ? ( -
- -
) : ( -
- +
+
)}
-

- {searchResult.available === true ? 'Available for Registration' : - searchResult.available === false ? 'Currently Registered' : 'Status Unknown'} -

-

- {searchResult.available === true ? 'Instant registration possible' : 'Check secondary market'} +

+ {searchResult.available ? 'Available' : 'Registered'} +

+

+ {searchResult.available + ? 'Ready for immediate registration' + : 'Currently owned by someone else'}

- {searchResult.available === true && ( + + {searchResult.available && ( - Register + Register Now )}
- {/* Auction Match */} + {/* Auction Card */} {searchResult.inAuction && searchResult.auctionData && ( -
-
-
- +
+
+
+
-

Auction Detected

-

- Current Bid: ${searchResult.auctionData.current_bid} • Ends in {searchResult.auctionData.time_remaining} +

+ In Auction + Live +

+

+ Current Bid: ${searchResult.auctionData.current_bid} • Ends in {searchResult.auctionData.time_remaining}

+ - Bid Now + Place Bid
)} - {/* Action Bar */} -
+ {/* Add to Watchlist */} +
)}
+ )} +
+ + {/* Helper Text */} + {!searchQuery && !searchFocused && ( +
+

+ Search across Global Registrars, Auctions, and Marketplaces simultaneously. +

)}
diff --git a/frontend/src/components/TerminalLayout.tsx b/frontend/src/components/TerminalLayout.tsx index 1490f76..26e9027 100755 --- a/frontend/src/components/TerminalLayout.tsx +++ b/frontend/src/components/TerminalLayout.tsx @@ -14,13 +14,15 @@ interface TerminalLayoutProps { title?: string subtitle?: string actions?: React.ReactNode + hideHeaderSearch?: boolean // New prop to control header elements } export function TerminalLayout({ children, title, subtitle, - actions + actions, + hideHeaderSearch = false }: TerminalLayoutProps) { const router = useRouter() const { isAuthenticated, isLoading, checkAuth, domains } = useStore() @@ -50,7 +52,7 @@ export function TerminalLayout({ useEffect(() => { if (!authCheckedRef.current) { authCheckedRef.current = true - checkAuth() + checkAuth() } }, [checkAuth]) @@ -107,8 +109,13 @@ export function TerminalLayout({ "ml-0 pt-16 lg:pt-0" )} > - {/* Top Bar */} -
+ {/* Top Bar - No longer sticky if hideHeaderSearch is true, or generally refined */} +
{/* Left: Title */}
@@ -122,104 +129,108 @@ export function TerminalLayout({ {/* Right: Actions */}
- {/* Quick Search */} - + {!hideHeaderSearch && ( + <> + {/* Quick Search */} + - {/* Mobile Search */} - + {/* Mobile Search */} + - {/* Notifications */} -
- - - {/* Notifications Dropdown */} - {notificationsOpen && ( -
-
-

Notifications

- -
-
- {availableDomains.length > 0 ? ( -
- {availableDomains.slice(0, 5).map((domain) => ( - setNotificationsOpen(false)} - className="flex items-start gap-3 p-3 hover:bg-foreground/5 rounded-lg transition-colors" - > -
- -
-
-

{domain.name}

-

Available now!

-
- - ))} -
- ) : ( -
- -

No notifications

-

- We'll notify you when domains become available -

-
+ {/* Notifications */} +
+
-
- )} -
+ > + + {hasNotifications && ( + + + + )} + - {/* Keyboard Shortcuts Hint */} - + {/* Notifications Dropdown */} + {notificationsOpen && ( +
+
+

Notifications

+ +
+
+ {availableDomains.length > 0 ? ( +
+ {availableDomains.slice(0, 5).map((domain) => ( + setNotificationsOpen(false)} + className="flex items-start gap-3 p-3 hover:bg-white/5 rounded-lg transition-colors" + > +
+ +
+
+

{domain.name}

+

Available now!

+
+ + ))} +
+ ) : ( +
+ +

No notifications

+

+ We'll notify you when domains become available +

+
+ )} +
+
+ )} +
+ + {/* Keyboard Shortcuts Hint */} + + + )} {/* Custom Actions */} {actions} @@ -235,7 +246,8 @@ export function TerminalLayout({
- {/* Quick Search Modal */} + {/* Quick Search Modal - Only if not hidden, or maybe still available via hotkey? + Let's keep it available via hotkey but hidden from UI if requested */} {searchOpen && (
)} - {/* Keyboard shortcut for search */} + {/* Keyboard shortcut for search - Still active unless strictly disabled */} setSearchOpen(true)} keys={['Meta', 'k']} />