From b5c456af1cd4425c37a90a289425c3bc0fe4e565 Mon Sep 17 00:00:00 2001 From: "yves.gugger" Date: Fri, 12 Dec 2025 16:35:34 +0100 Subject: [PATCH] refactor: Rename Intel to Discover and apply Landing Page style - Renamed /intel to /discover - Updated styles to match dark/cinematic landing page theme - Updated Header, Footer, and Sitemap - Added redirects from /intel and /tld-pricing to /discover - Optimized SEO metadata for new paths --- backend/app/routes/portfolio.py | 542 +++++++ backend/scripts/seed_auctions.py | 36 + frontend/next.config.js | 22 + frontend/public/robots.txt | 6 +- frontend/src/app/auctions/layout.tsx | 106 ++ frontend/src/app/auctions/page.tsx | 4 +- frontend/src/app/careers/page.tsx | 209 +++ frontend/src/app/command/alerts/page.tsx | 597 +++++++ frontend/src/app/command/auctions/page.tsx | 578 +++++++ frontend/src/app/command/dashboard/page.tsx | 402 +++++ frontend/src/app/command/listings/page.tsx | 582 +++++++ frontend/src/app/command/marketplace/page.tsx | 302 ++++ frontend/src/app/command/page.tsx | 19 + frontend/src/app/command/portfolio/page.tsx | 955 ++++++++++++ .../src/app/command/pricing/[tld]/page.tsx | 722 +++++++++ frontend/src/app/command/pricing/page.tsx | 387 +++++ frontend/src/app/command/seo/page.tsx | 508 ++++++ frontend/src/app/command/settings/page.tsx | 563 +++++++ frontend/src/app/command/watchlist/page.tsx | 620 ++++++++ frontend/src/app/command/welcome/page.tsx | 221 +++ frontend/src/app/dashboard/page.tsx | 1105 +++++++++++++ .../app/{intel => discover}/[tld]/metadata.ts | 12 +- .../app/{intel => discover}/[tld]/page.tsx | 323 ++-- frontend/src/app/{intel => discover}/page.tsx | 202 +-- frontend/src/app/intelligence/page.tsx | 26 + frontend/src/app/market/page.tsx | 4 +- frontend/src/app/page.tsx | 1379 +++++++---------- frontend/src/app/settings/page.tsx | 743 +++++++++ frontend/src/app/sitemap.ts | 4 +- frontend/src/app/terminal/portfolio/page.tsx | 987 ++++++++++++ frontend/src/app/tld-pricing/[tld]/page.tsx | 6 +- frontend/src/app/tld-pricing/page.tsx | 6 +- frontend/src/components/DomainChecker.tsx | 294 ++-- frontend/src/components/Footer.tsx | 4 +- frontend/src/components/Header.tsx | 31 +- 35 files changed, 11279 insertions(+), 1228 deletions(-) create mode 100755 backend/app/routes/portfolio.py create mode 100755 backend/scripts/seed_auctions.py create mode 100755 frontend/src/app/auctions/layout.tsx create mode 100755 frontend/src/app/careers/page.tsx create mode 100755 frontend/src/app/command/alerts/page.tsx create mode 100755 frontend/src/app/command/auctions/page.tsx create mode 100755 frontend/src/app/command/dashboard/page.tsx create mode 100755 frontend/src/app/command/listings/page.tsx create mode 100755 frontend/src/app/command/marketplace/page.tsx create mode 100755 frontend/src/app/command/page.tsx create mode 100755 frontend/src/app/command/portfolio/page.tsx create mode 100755 frontend/src/app/command/pricing/[tld]/page.tsx create mode 100755 frontend/src/app/command/pricing/page.tsx create mode 100755 frontend/src/app/command/seo/page.tsx create mode 100755 frontend/src/app/command/settings/page.tsx create mode 100755 frontend/src/app/command/watchlist/page.tsx create mode 100755 frontend/src/app/command/welcome/page.tsx create mode 100755 frontend/src/app/dashboard/page.tsx rename frontend/src/app/{intel => discover}/[tld]/metadata.ts (94%) rename frontend/src/app/{intel => discover}/[tld]/page.tsx (72%) rename frontend/src/app/{intel => discover}/page.tsx (68%) create mode 100755 frontend/src/app/intelligence/page.tsx create mode 100755 frontend/src/app/settings/page.tsx create mode 100755 frontend/src/app/terminal/portfolio/page.tsx diff --git a/backend/app/routes/portfolio.py b/backend/app/routes/portfolio.py new file mode 100755 index 0000000..543cb32 --- /dev/null +++ b/backend/app/routes/portfolio.py @@ -0,0 +1,542 @@ +"""Portfolio API routes.""" +from datetime import datetime +from typing import Optional, List +from fastapi import APIRouter, Depends, HTTPException, status, Query +from pydantic import BaseModel, Field +from sqlalchemy import select, func, and_ +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database import get_db +from app.routes.auth import get_current_user +from app.models.user import User +from app.models.portfolio import PortfolioDomain, DomainValuation +from app.services.valuation import valuation_service + +router = APIRouter(prefix="/portfolio", tags=["portfolio"]) + + +# ============== Schemas ============== + +class PortfolioDomainCreate(BaseModel): + """Schema for creating a portfolio domain.""" + domain: str = Field(..., min_length=3, max_length=255) + purchase_date: Optional[datetime] = None + purchase_price: Optional[float] = Field(None, ge=0) + purchase_registrar: Optional[str] = None + registrar: Optional[str] = None + renewal_date: Optional[datetime] = None + renewal_cost: Optional[float] = Field(None, ge=0) + auto_renew: bool = True + notes: Optional[str] = None + tags: Optional[str] = None + + +class PortfolioDomainUpdate(BaseModel): + """Schema for updating a portfolio domain.""" + purchase_date: Optional[datetime] = None + purchase_price: Optional[float] = Field(None, ge=0) + purchase_registrar: Optional[str] = None + registrar: Optional[str] = None + renewal_date: Optional[datetime] = None + renewal_cost: Optional[float] = Field(None, ge=0) + auto_renew: Optional[bool] = None + status: Optional[str] = None + notes: Optional[str] = None + tags: Optional[str] = None + + +class PortfolioDomainSell(BaseModel): + """Schema for marking a domain as sold.""" + sale_date: datetime + sale_price: float = Field(..., ge=0) + + +class PortfolioDomainResponse(BaseModel): + """Response schema for portfolio domain.""" + id: int + domain: str + purchase_date: Optional[datetime] + purchase_price: Optional[float] + purchase_registrar: Optional[str] + registrar: Optional[str] + renewal_date: Optional[datetime] + renewal_cost: Optional[float] + auto_renew: bool + estimated_value: Optional[float] + value_updated_at: Optional[datetime] + is_sold: bool + sale_date: Optional[datetime] + sale_price: Optional[float] + status: str + notes: Optional[str] + tags: Optional[str] + roi: Optional[float] + created_at: datetime + updated_at: datetime + + class Config: + from_attributes = True + + +class PortfolioSummary(BaseModel): + """Summary of user's portfolio.""" + total_domains: int + active_domains: int + sold_domains: int + total_invested: float + total_value: float + total_sold_value: float + unrealized_profit: float + realized_profit: float + overall_roi: float + + +class ValuationResponse(BaseModel): + """Response schema for domain valuation.""" + domain: str + estimated_value: float + currency: str + scores: dict + factors: dict + confidence: str + source: str + calculated_at: str + + +# ============== Portfolio Endpoints ============== + +@router.get("", response_model=List[PortfolioDomainResponse]) +async def get_portfolio( + status: Optional[str] = Query(None, description="Filter by status"), + sort_by: str = Query("created_at", description="Sort field"), + sort_order: str = Query("desc", description="Sort order (asc/desc)"), + limit: int = Query(100, le=500), + offset: int = Query(0, ge=0), + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Get user's portfolio domains.""" + query = select(PortfolioDomain).where(PortfolioDomain.user_id == current_user.id) + + # Filter by status + if status: + query = query.where(PortfolioDomain.status == status) + + # Sorting + sort_column = getattr(PortfolioDomain, sort_by, PortfolioDomain.created_at) + if sort_order == "asc": + query = query.order_by(sort_column.asc()) + else: + query = query.order_by(sort_column.desc()) + + # Pagination + query = query.offset(offset).limit(limit) + + result = await db.execute(query) + domains = result.scalars().all() + + # Calculate ROI for each domain + responses = [] + for d in domains: + response = PortfolioDomainResponse( + id=d.id, + domain=d.domain, + purchase_date=d.purchase_date, + purchase_price=d.purchase_price, + purchase_registrar=d.purchase_registrar, + registrar=d.registrar, + renewal_date=d.renewal_date, + renewal_cost=d.renewal_cost, + auto_renew=d.auto_renew, + estimated_value=d.estimated_value, + value_updated_at=d.value_updated_at, + is_sold=d.is_sold, + sale_date=d.sale_date, + sale_price=d.sale_price, + status=d.status, + notes=d.notes, + tags=d.tags, + roi=d.roi, + created_at=d.created_at, + updated_at=d.updated_at, + ) + responses.append(response) + + return responses + + +@router.get("/summary", response_model=PortfolioSummary) +async def get_portfolio_summary( + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Get portfolio summary statistics.""" + result = await db.execute( + select(PortfolioDomain).where(PortfolioDomain.user_id == current_user.id) + ) + domains = result.scalars().all() + + total_domains = len(domains) + active_domains = sum(1 for d in domains if d.status == "active" and not d.is_sold) + sold_domains = sum(1 for d in domains if d.is_sold) + + total_invested = sum(d.purchase_price or 0 for d in domains) + total_value = sum(d.estimated_value or 0 for d in domains if not d.is_sold) + total_sold_value = sum(d.sale_price or 0 for d in domains if d.is_sold) + + # Calculate active investment for ROI + active_investment = sum(d.purchase_price or 0 for d in domains if not d.is_sold) + sold_investment = sum(d.purchase_price or 0 for d in domains if d.is_sold) + + unrealized_profit = total_value - active_investment + realized_profit = total_sold_value - sold_investment + + overall_roi = 0.0 + if total_invested > 0: + overall_roi = ((total_value + total_sold_value - total_invested) / total_invested) * 100 + + return PortfolioSummary( + total_domains=total_domains, + active_domains=active_domains, + sold_domains=sold_domains, + total_invested=round(total_invested, 2), + total_value=round(total_value, 2), + total_sold_value=round(total_sold_value, 2), + unrealized_profit=round(unrealized_profit, 2), + realized_profit=round(realized_profit, 2), + overall_roi=round(overall_roi, 2), + ) + + +@router.post("", response_model=PortfolioDomainResponse, status_code=status.HTTP_201_CREATED) +async def add_portfolio_domain( + data: PortfolioDomainCreate, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Add a domain to portfolio.""" + # Check if domain already exists in user's portfolio + existing = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.user_id == current_user.id, + PortfolioDomain.domain == data.domain.lower(), + ) + ) + ) + if existing.scalar_one_or_none(): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Domain already in portfolio", + ) + + # Get initial valuation + valuation = await valuation_service.estimate_value(data.domain, db, save_result=True) + estimated_value = valuation.get("estimated_value") if "error" not in valuation else None + + # Create portfolio entry + domain = PortfolioDomain( + user_id=current_user.id, + domain=data.domain.lower(), + purchase_date=data.purchase_date, + purchase_price=data.purchase_price, + purchase_registrar=data.purchase_registrar, + registrar=data.registrar or data.purchase_registrar, + renewal_date=data.renewal_date, + renewal_cost=data.renewal_cost, + auto_renew=data.auto_renew, + estimated_value=estimated_value, + value_updated_at=datetime.utcnow() if estimated_value else None, + notes=data.notes, + tags=data.tags, + ) + + db.add(domain) + await db.commit() + await db.refresh(domain) + + return PortfolioDomainResponse( + id=domain.id, + domain=domain.domain, + purchase_date=domain.purchase_date, + purchase_price=domain.purchase_price, + purchase_registrar=domain.purchase_registrar, + registrar=domain.registrar, + renewal_date=domain.renewal_date, + renewal_cost=domain.renewal_cost, + auto_renew=domain.auto_renew, + estimated_value=domain.estimated_value, + value_updated_at=domain.value_updated_at, + is_sold=domain.is_sold, + sale_date=domain.sale_date, + sale_price=domain.sale_price, + status=domain.status, + notes=domain.notes, + tags=domain.tags, + roi=domain.roi, + created_at=domain.created_at, + updated_at=domain.updated_at, + ) + + +@router.get("/{domain_id}", response_model=PortfolioDomainResponse) +async def get_portfolio_domain( + domain_id: int, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Get a specific portfolio domain.""" + result = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.id == domain_id, + PortfolioDomain.user_id == current_user.id, + ) + ) + ) + domain = result.scalar_one_or_none() + + if not domain: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Domain not found in portfolio", + ) + + return PortfolioDomainResponse( + id=domain.id, + domain=domain.domain, + purchase_date=domain.purchase_date, + purchase_price=domain.purchase_price, + purchase_registrar=domain.purchase_registrar, + registrar=domain.registrar, + renewal_date=domain.renewal_date, + renewal_cost=domain.renewal_cost, + auto_renew=domain.auto_renew, + estimated_value=domain.estimated_value, + value_updated_at=domain.value_updated_at, + is_sold=domain.is_sold, + sale_date=domain.sale_date, + sale_price=domain.sale_price, + status=domain.status, + notes=domain.notes, + tags=domain.tags, + roi=domain.roi, + created_at=domain.created_at, + updated_at=domain.updated_at, + ) + + +@router.put("/{domain_id}", response_model=PortfolioDomainResponse) +async def update_portfolio_domain( + domain_id: int, + data: PortfolioDomainUpdate, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Update a portfolio domain.""" + result = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.id == domain_id, + PortfolioDomain.user_id == current_user.id, + ) + ) + ) + domain = result.scalar_one_or_none() + + if not domain: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Domain not found in portfolio", + ) + + # Update fields + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(domain, field, value) + + await db.commit() + await db.refresh(domain) + + return PortfolioDomainResponse( + id=domain.id, + domain=domain.domain, + purchase_date=domain.purchase_date, + purchase_price=domain.purchase_price, + purchase_registrar=domain.purchase_registrar, + registrar=domain.registrar, + renewal_date=domain.renewal_date, + renewal_cost=domain.renewal_cost, + auto_renew=domain.auto_renew, + estimated_value=domain.estimated_value, + value_updated_at=domain.value_updated_at, + is_sold=domain.is_sold, + sale_date=domain.sale_date, + sale_price=domain.sale_price, + status=domain.status, + notes=domain.notes, + tags=domain.tags, + roi=domain.roi, + created_at=domain.created_at, + updated_at=domain.updated_at, + ) + + +@router.post("/{domain_id}/sell", response_model=PortfolioDomainResponse) +async def mark_domain_sold( + domain_id: int, + data: PortfolioDomainSell, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Mark a domain as sold.""" + result = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.id == domain_id, + PortfolioDomain.user_id == current_user.id, + ) + ) + ) + domain = result.scalar_one_or_none() + + if not domain: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Domain not found in portfolio", + ) + + domain.is_sold = True + domain.sale_date = data.sale_date + domain.sale_price = data.sale_price + domain.status = "sold" + + await db.commit() + await db.refresh(domain) + + return PortfolioDomainResponse( + id=domain.id, + domain=domain.domain, + purchase_date=domain.purchase_date, + purchase_price=domain.purchase_price, + purchase_registrar=domain.purchase_registrar, + registrar=domain.registrar, + renewal_date=domain.renewal_date, + renewal_cost=domain.renewal_cost, + auto_renew=domain.auto_renew, + estimated_value=domain.estimated_value, + value_updated_at=domain.value_updated_at, + is_sold=domain.is_sold, + sale_date=domain.sale_date, + sale_price=domain.sale_price, + status=domain.status, + notes=domain.notes, + tags=domain.tags, + roi=domain.roi, + created_at=domain.created_at, + updated_at=domain.updated_at, + ) + + +@router.delete("/{domain_id}", status_code=status.HTTP_204_NO_CONTENT) +async def delete_portfolio_domain( + domain_id: int, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Delete a domain from portfolio.""" + result = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.id == domain_id, + PortfolioDomain.user_id == current_user.id, + ) + ) + ) + domain = result.scalar_one_or_none() + + if not domain: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Domain not found in portfolio", + ) + + await db.delete(domain) + await db.commit() + + +@router.post("/{domain_id}/refresh-value", response_model=PortfolioDomainResponse) +async def refresh_domain_value( + domain_id: int, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Refresh the estimated value of a portfolio domain.""" + result = await db.execute( + select(PortfolioDomain).where( + and_( + PortfolioDomain.id == domain_id, + PortfolioDomain.user_id == current_user.id, + ) + ) + ) + domain = result.scalar_one_or_none() + + if not domain: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Domain not found in portfolio", + ) + + # Get new valuation + valuation = await valuation_service.estimate_value(domain.domain, db, save_result=True) + + if "error" not in valuation: + domain.estimated_value = valuation["estimated_value"] + domain.value_updated_at = datetime.utcnow() + await db.commit() + await db.refresh(domain) + + return PortfolioDomainResponse( + id=domain.id, + domain=domain.domain, + purchase_date=domain.purchase_date, + purchase_price=domain.purchase_price, + purchase_registrar=domain.purchase_registrar, + registrar=domain.registrar, + renewal_date=domain.renewal_date, + renewal_cost=domain.renewal_cost, + auto_renew=domain.auto_renew, + estimated_value=domain.estimated_value, + value_updated_at=domain.value_updated_at, + is_sold=domain.is_sold, + sale_date=domain.sale_date, + sale_price=domain.sale_price, + status=domain.status, + notes=domain.notes, + tags=domain.tags, + roi=domain.roi, + created_at=domain.created_at, + updated_at=domain.updated_at, + ) + + +# ============== Valuation Endpoints ============== + +@router.get("/valuation/{domain}", response_model=ValuationResponse) +async def get_domain_valuation( + domain: str, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Get estimated value for any domain.""" + valuation = await valuation_service.estimate_value(domain, db, save_result=True) + + if "error" in valuation: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=valuation["error"], + ) + + return ValuationResponse(**valuation) + diff --git a/backend/scripts/seed_auctions.py b/backend/scripts/seed_auctions.py new file mode 100755 index 0000000..bc0f975 --- /dev/null +++ b/backend/scripts/seed_auctions.py @@ -0,0 +1,36 @@ +"""Seed auction data for development.""" +import asyncio +import sys +import os + +# Add parent directory to path +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from app.database import AsyncSessionLocal +from app.services.auction_scraper import auction_scraper + + +async def main(): + """Seed auction data.""" + async with AsyncSessionLocal() as db: + print("Seeding sample auction data...") + result = await auction_scraper.seed_sample_auctions(db) + print(f"✓ Seeded {result['found']} auctions ({result['new']} new, {result['updated']} updated)") + + # Also try to scrape real data + print("\nAttempting to scrape real auction data...") + try: + scrape_result = await auction_scraper.scrape_all_platforms(db) + print(f"✓ Scraped {scrape_result['total_found']} auctions from platforms:") + for platform, stats in scrape_result['platforms'].items(): + print(f" - {platform}: {stats.get('found', 0)} found") + if scrape_result['errors']: + print(f" Errors: {scrape_result['errors']}") + except Exception as e: + print(f" Scraping failed (this is okay): {e}") + + print("\n✓ Done!") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/frontend/next.config.js b/frontend/next.config.js index 3ebd517..a34a437 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -103,6 +103,28 @@ const nextConfig = { destination: '/terminal/intel/:tld*', permanent: true, }, + // Public Intel → Discover + { + source: '/intel', + destination: '/discover', + permanent: true, + }, + { + source: '/intel/:tld*', + destination: '/discover/:tld*', + permanent: true, + }, + // Old TLD pricing → Discover + { + source: '/tld-pricing', + destination: '/discover', + permanent: true, + }, + { + source: '/tld-pricing/:tld*', + destination: '/discover/:tld*', + permanent: true, + }, // Listings → LISTING { source: '/terminal/listings', diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt index 786c58a..d6ab936 100644 --- a/frontend/public/robots.txt +++ b/frontend/public/robots.txt @@ -9,9 +9,9 @@ Disallow: /forgot-password Disallow: /reset-password # Allow specific public pages -Allow: /intel/$ -Allow: /intel/*.css -Allow: /intel/*.js +Allow: /discover/$ +Allow: /discover/*.css +Allow: /discover/*.js Allow: /market Allow: /pricing Allow: /about diff --git a/frontend/src/app/auctions/layout.tsx b/frontend/src/app/auctions/layout.tsx new file mode 100755 index 0000000..7438375 --- /dev/null +++ b/frontend/src/app/auctions/layout.tsx @@ -0,0 +1,106 @@ +import { Metadata } from 'next' + +const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://pounce.ch' + +export const metadata: Metadata = { + title: 'Domain Auctions — Smart Pounce', + description: 'Find undervalued domain auctions from GoDaddy, Sedo, NameJet, SnapNames & DropCatch. Our Smart Pounce algorithm identifies the best opportunities with transparent valuations.', + keywords: [ + 'domain auctions', + 'expired domains', + 'domain bidding', + 'GoDaddy auctions', + 'Sedo domains', + 'NameJet', + 'domain investment', + 'undervalued domains', + 'domain flipping', + ], + openGraph: { + title: 'Domain Auctions — Smart Pounce by pounce', + description: 'Find undervalued domain auctions. Transparent valuations, multiple platforms, no payment handling.', + url: `${siteUrl}/auctions`, + type: 'website', + images: [ + { + url: `${siteUrl}/og-auctions.png`, + width: 1200, + height: 630, + alt: 'Smart Pounce - Domain Auction Aggregator', + }, + ], + }, + twitter: { + card: 'summary_large_image', + title: 'Domain Auctions — Smart Pounce', + description: 'Find undervalued domain auctions from GoDaddy, Sedo, NameJet & more.', + }, + alternates: { + canonical: `${siteUrl}/auctions`, + }, +} + +// JSON-LD for Auctions page +const jsonLd = { + '@context': 'https://schema.org', + '@type': 'WebPage', + name: 'Domain Auctions — Smart Pounce', + description: 'Aggregated domain auctions from multiple platforms with transparent algorithmic valuations.', + url: `${siteUrl}/auctions`, + isPartOf: { + '@type': 'WebSite', + name: 'pounce', + url: siteUrl, + }, + about: { + '@type': 'Service', + name: 'Smart Pounce', + description: 'Domain auction aggregation and opportunity analysis', + provider: { + '@type': 'Organization', + name: 'pounce', + }, + }, + mainEntity: { + '@type': 'ItemList', + name: 'Domain Auctions', + description: 'Live domain auctions from GoDaddy, Sedo, NameJet, SnapNames, and DropCatch', + itemListElement: [ + { + '@type': 'ListItem', + position: 1, + name: 'GoDaddy Auctions', + url: 'https://auctions.godaddy.com', + }, + { + '@type': 'ListItem', + position: 2, + name: 'Sedo', + url: 'https://sedo.com', + }, + { + '@type': 'ListItem', + position: 3, + name: 'NameJet', + url: 'https://namejet.com', + }, + ], + }, +} + +export default function AuctionsLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + <> +