-
-
-
{domain.domain}
- {domain.status === 'sold' && Sold}
-
-
- {domain.purchase_price && {formatCurrency(domain.purchase_price)}}
- {domain.estimated_value && {formatCurrency(domain.estimated_value)}}
- {renewal && {renewal.text}}
- {domain.registrar && {domain.registrar}}
-
-
-
- {roi !== null && (
-
= 0 ? "bg-accent/10" : "bg-danger/10")}>
-
ROI
-
= 0 ? "text-accent" : "text-danger")}>{roi >= 0 ? '+' : ''}{roi.toFixed(1)}%
+
+
+
+
+ | Domain |
+ Purchased |
+ Value |
+ Renewal |
+ ROI |
+ Actions |
+
+
+
+ {portfolio.map((domain) => {
+ const roi = domain.roi
+ const renewal = formatExpirationDate(domain.renewal_date)
+ return (
+
+
+
+
+
+ {domain.domain}
+ {domain.status === 'sold' && Sold}
+ {domain.registrar && {domain.registrar} }
+
- )}
-
- {domain.status !== 'sold' && }
-
-
-
-
-
-
- {domain.notes && {domain.notes} }
-
- )
- })}
+ |
+
+ {domain.purchase_price ? formatCurrency(domain.purchase_price) : '—'}
+ {domain.purchase_date && {new Date(domain.purchase_date).toLocaleDateString()} }
+ |
+
+ {domain.estimated_value ? formatCurrency(domain.estimated_value) : '—'}
+ |
+
+ {renewal ? (
+
+ {renewal.text}
+
+ ) : —}
+ |
+
+ {roi !== null ? (
+ = 0 ? "text-accent" : "text-danger")}>
+ {roi >= 0 ? '+' : ''}{roi.toFixed(1)}%
+
+ ) : —}
+ |
+
+
+ {domain.status !== 'sold' && (
+
+ )}
+
+
+
+
+ |
+
+ )
+ })}
+
+
)}
)}
-
- {/* Quick Links */}
-
-
-
-
-
-
-
TLD Price Intelligence
-
Track 886+ domain extensions in real-time
-
-
-
- Explore Prices
-
-
-
diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx
index 9a2775f..e6eea63 100644
--- a/frontend/src/components/Header.tsx
+++ b/frontend/src/components/Header.tsx
@@ -2,12 +2,37 @@
import Link from 'next/link'
import { useStore } from '@/lib/store'
-import { LogOut, LayoutDashboard, Menu, X, Settings } from 'lucide-react'
-import { useState } from 'react'
+import { LogOut, LayoutDashboard, Menu, X, Settings, Bell, User, ChevronDown, TrendingUp, Briefcase, Eye } from 'lucide-react'
+import { useState, useRef, useEffect } from 'react'
+import clsx from 'clsx'
export function Header() {
- const { isAuthenticated, user, logout } = useStore()
+ const { isAuthenticated, user, logout, domains, subscription } = useStore()
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
+ const [userMenuOpen, setUserMenuOpen] = useState(false)
+ const [notificationsOpen, setNotificationsOpen] = useState(false)
+ const userMenuRef = useRef
(null)
+ const notificationsRef = useRef(null)
+
+ // Close dropdowns when clicking outside
+ useEffect(() => {
+ function handleClickOutside(event: MouseEvent) {
+ if (userMenuRef.current && !userMenuRef.current.contains(event.target as Node)) {
+ setUserMenuOpen(false)
+ }
+ if (notificationsRef.current && !notificationsRef.current.contains(event.target as Node)) {
+ setNotificationsOpen(false)
+ }
+ }
+ document.addEventListener('mousedown', handleClickOutside)
+ return () => document.removeEventListener('mousedown', handleClickOutside)
+ }, [])
+
+ // Count notifications (available domains, etc.)
+ const availableDomains = domains?.filter(d => d.is_available) || []
+ const hasNotifications = availableDomains.length > 0
+
+ const tierName = subscription?.tier_name || subscription?.tier || 'Scout'
return (
@@ -50,51 +75,165 @@ export function Header() {
>
Auctions
-
- Plans
-
+ {!isAuthenticated && (
+
+ Plans
+
+ )}