diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx index ab61950..ea4a867 100644 --- a/frontend/src/app/dashboard/page.tsx +++ b/frontend/src/app/dashboard/page.tsx @@ -36,6 +36,10 @@ import { Globe, ArrowUpRight, ArrowDownRight, + Radio, + CircleCheck, + CircleX, + CircleAlert, } from 'lucide-react' import clsx from 'clsx' import Link from 'next/link' @@ -370,12 +374,59 @@ export default function DashboardPage() { const isProOrHigher = tierName === 'Professional' || tierName === 'Enterprise' || tierName === 'Trader' || tierName === 'Tycoon' const isEnterprise = tierName === 'Enterprise' || tierName === 'Tycoon' + // Get domain status with icon + const getDomainStatus = (domain: any) => { + const exp = formatExpirationDate(domain.expiration_date) + + if (domain.is_available) { + return { + icon: CircleCheck, + label: 'Available', + color: 'text-emerald-400', + bg: 'bg-emerald-400/10', + ring: 'ring-emerald-400/30', + pulse: false + } + } + + if (exp?.urgent) { + return { + icon: CircleAlert, + label: 'Expiring', + color: 'text-amber-400', + bg: 'bg-amber-400/10', + ring: 'ring-amber-400/30', + pulse: true + } + } + + if (domain.notify_on_available) { + return { + icon: Radio, + label: 'Monitoring', + color: 'text-cyan-400', + bg: 'bg-cyan-400/10', + ring: 'ring-cyan-400/30', + pulse: true + } + } + + return { + icon: CircleX, + label: 'Registered', + color: 'text-foreground-subtle', + bg: 'bg-foreground/5', + ring: 'ring-foreground/10', + pulse: false + } + } + return (
-
-
+
+
{/* Header */}
@@ -409,28 +460,42 @@ export default function DashboardPage() {
{/* Tabs */} -
+
@@ -447,21 +512,49 @@ export default function DashboardPage() {
{/* Stats Row */}
-
-

Tracked

-

{domains.length}

+
+
+
+ +
+

Tracked

+
+

{domains.length}

-
-

Available

-

{availableCount}

+
+
+
+ +
+

Available

+
+

{availableCount}

-
-

Registered

-

{domains.length - availableCount}

+
+
+
+ +
+

Monitoring

+
+

{domains.filter(d => d.notify_on_available).length}

-
0 ? "bg-warning/5 border-warning/20" : "bg-background-secondary border-border")}> -

0 ? "text-warning/70" : "text-foreground-muted")}>Expiring

-

0 ? "text-warning" : "text-foreground")}>{expiringCount}

+
0 + ? "bg-amber-500/5 border-amber-500/20 hover:border-amber-500/40" + : "bg-background-secondary/50 border-border hover:border-foreground/20" + )}> +
+
0 ? "bg-amber-500/20" : "bg-foreground/10" + )}> + 0 ? "text-amber-400" : "text-foreground-muted")} /> +
+

0 ? "text-amber-400/80" : "text-foreground-muted")}>Expiring

+
+

0 ? "text-amber-400" : "text-foreground")}>{expiringCount}

@@ -486,73 +579,102 @@ export default function DashboardPage() { {/* Domain Table */} {domains.length === 0 ? ( -
- -

No domains yet

-

Add your first domain above

+
+
+ +
+

No domains tracked yet

+

Add your first domain above to start monitoring

) : ( -
+
- + - - - - - + + + + + - + {domains.map((domain) => { const exp = formatExpirationDate(domain.expiration_date) + const status = getDomainStatus(domain) + const StatusIcon = status.icon return ( - - + - - - -
DomainStatusExpirationLast CheckActionsDomainStatusExpirationLast CheckActions
-
-
- {domain.name} +
+
+
+ + {status.pulse && ( + + )} +
+
+ {domain.name} +

{status.label}

+
- - {domain.is_available ? 'Available' : 'Registered'} + + + {status.label} + {exp ? ( - + {exp.text} - ) : } + ) : } - + + {formatDate(domain.last_checked)} -
+
+
{isProOrHigher && ( - )} - - -
@@ -573,42 +695,82 @@ export default function DashboardPage() { {/* Portfolio Stats */} {portfolioSummary && (
-
-

Total Value

-

{formatCurrency(portfolioSummary.total_value)}

+
+
+
+ +
+

Total Value

+
+

{formatCurrency(portfolioSummary.total_value)}

-
-

Invested

-

{formatCurrency(portfolioSummary.total_invested)}

+
+
+
+ +
+

Invested

+
+

{formatCurrency(portfolioSummary.total_invested)}

-
= 0 ? "bg-accent/5 border-accent/20" : "bg-danger/5 border-danger/20")}> -

= 0 ? "text-accent/70" : "text-danger/70")}>P/L

-

= 0 ? "text-accent" : "text-danger")}> - {portfolioSummary.unrealized_profit >= 0 ? : } - {formatCurrency(Math.abs(portfolioSummary.unrealized_profit))} +

= 0 + ? "bg-emerald-500/5 border-emerald-500/20 hover:border-emerald-500/40" + : "bg-rose-500/5 border-rose-500/20 hover:border-rose-500/40" + )}> +
+
= 0 ? "bg-emerald-500/20" : "bg-rose-500/20" + )}> + {portfolioSummary.unrealized_profit >= 0 + ? + : + } +
+

= 0 ? "text-emerald-400/80" : "text-rose-400/80")}>P/L

+
+

= 0 ? "text-emerald-400" : "text-rose-400")}> + {portfolioSummary.unrealized_profit >= 0 ? '+' : ''}{formatCurrency(portfolioSummary.unrealized_profit)}

-
= 0 ? "bg-accent/5 border-accent/20" : "bg-danger/5 border-danger/20")}> -

= 0 ? "text-accent/70" : "text-danger/70")}>ROI

-

= 0 ? "text-accent" : "text-danger")}> +

= 0 + ? "bg-emerald-500/5 border-emerald-500/20 hover:border-emerald-500/40" + : "bg-rose-500/5 border-rose-500/20 hover:border-rose-500/40" + )}> +
+
= 0 ? "bg-emerald-500/20" : "bg-rose-500/20" + )}> + = 0 ? "text-emerald-400" : "text-rose-400")} /> +
+

= 0 ? "text-emerald-400/80" : "text-rose-400/80")}>ROI

+
+

= 0 ? "text-emerald-400" : "text-rose-400")}> {portfolioSummary.overall_roi >= 0 ? '+' : ''}{portfolioSummary.overall_roi.toFixed(1)}%

)} - {loadingPortfolio ? ( -
+
) : portfolio.length === 0 ? ( -
- -

Portfolio is empty

-

Add domains you own to track their value

+
+
+ +
+

Your portfolio is empty

+

Add domains you own to track their value and ROI

) : (
@@ -655,18 +817,19 @@ export default function DashboardPage() { )} {/* Quick Links */} -
+
-
- +
+
-

TLD Price Intelligence

-

Track 886+ domain extensions

+

TLD Price Intelligence

+

Track 886+ domain extensions in real-time

- - Explore + + Explore Prices +