From ff8d6e8eb1971b288e9e96833ab76a9c58a70001 Mon Sep 17 00:00:00 2001 From: "yves.gugger" Date: Wed, 10 Dec 2025 11:50:48 +0100 Subject: [PATCH] fix: API routing + Landing page improvements API FIX: - Fixed /listings/my returning 404 - Moved /my endpoint BEFORE /{slug} dynamic route - FastAPI now correctly matches /my before treating it as slug LANDING PAGE: - Added visual transitions between sections - Improved 'Beyond Hunting' section with better styling - Added background patterns and gradient transitions - Enhanced feature cards with corner accents - Better visual flow between sections --- backend/app/api/listings.py | 92 ++++++++-------- frontend/src/app/page.tsx | 208 +++++++++++++++++++++++------------- 2 files changed, 179 insertions(+), 121 deletions(-) diff --git a/backend/app/api/listings.py b/backend/app/api/listings.py index 4f9543e..2f4ffb2 100644 --- a/backend/app/api/listings.py +++ b/backend/app/api/listings.py @@ -255,6 +255,53 @@ async def browse_listings( return responses +# ============== Authenticated Endpoints (before dynamic routes!) ============== + +@router.get("/my", response_model=List[ListingResponse]) +async def get_my_listings( + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + """Get current user's listings.""" + result = await db.execute( + select(DomainListing) + .where(DomainListing.user_id == current_user.id) + .order_by(DomainListing.created_at.desc()) + ) + listings = list(result.scalars().all()) + + return [ + ListingResponse( + id=listing.id, + domain=listing.domain, + slug=listing.slug, + title=listing.title, + description=listing.description, + asking_price=listing.asking_price, + min_offer=listing.min_offer, + currency=listing.currency, + price_type=listing.price_type, + pounce_score=listing.pounce_score, + estimated_value=listing.estimated_value, + verification_status=listing.verification_status, + is_verified=listing.is_verified, + status=listing.status, + show_valuation=listing.show_valuation, + allow_offers=listing.allow_offers, + view_count=listing.view_count, + inquiry_count=listing.inquiry_count, + public_url=listing.public_url, + created_at=listing.created_at, + published_at=listing.published_at, + seller_verified=current_user.is_verified, + seller_member_since=current_user.created_at, + ) + for listing in listings + ] + + +# ============== Public Dynamic Routes ============== + @router.get("/{slug}", response_model=ListingPublicResponse) async def get_listing_by_slug( slug: str, @@ -381,7 +428,7 @@ async def submit_inquiry( } -# ============== Authenticated Endpoints ============== +# ============== Listing Management (Authenticated) ============== @router.post("", response_model=ListingResponse) async def create_listing( @@ -485,49 +532,6 @@ async def create_listing( ) -@router.get("/my", response_model=List[ListingResponse]) -async def get_my_listings( - current_user: User = Depends(get_current_user), - db: AsyncSession = Depends(get_db), -): - """Get current user's listings.""" - result = await db.execute( - select(DomainListing) - .where(DomainListing.user_id == current_user.id) - .order_by(DomainListing.created_at.desc()) - ) - listings = list(result.scalars().all()) - - return [ - ListingResponse( - id=listing.id, - domain=listing.domain, - slug=listing.slug, - title=listing.title, - description=listing.description, - asking_price=listing.asking_price, - min_offer=listing.min_offer, - currency=listing.currency, - price_type=listing.price_type, - pounce_score=listing.pounce_score, - estimated_value=listing.estimated_value, - verification_status=listing.verification_status, - is_verified=listing.is_verified, - status=listing.status, - show_valuation=listing.show_valuation, - allow_offers=listing.allow_offers, - view_count=listing.view_count, - inquiry_count=listing.inquiry_count, - public_url=listing.public_url, - created_at=listing.created_at, - published_at=listing.published_at, - seller_verified=current_user.is_verified, - seller_member_since=current_user.created_at, - ) - for listing in listings - ] - - @router.get("/{id}/inquiries", response_model=List[InquiryResponse]) async def get_listing_inquiries( id: int, diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index 31c0d6b..bc5e787 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -370,98 +370,152 @@ export default function HomePage() { - {/* New Features: For Sale + Sniper Alerts */} -
-
-
- New Features -

- More than hunting. + {/* Transition Element */} +
+
+
+
+
+
+ + {/* Beyond Hunting: Sell & Alert */} +
+ {/* Subtle background pattern */} +
+
+
+
+ +
+ {/* Section Header - Left aligned for flow */} +
+
+
+ Beyond Hunting +
+

+ Buy. Sell. Get alerted.

+

+ Pounce isn't just for finding domains. It's your complete domain business platform. +

{/* For Sale Marketplace */} -
-
-
- -
-
-

Sell Your Domains

-

Marketplace

+
+ {/* Corner accent */} +
+ +
+
+
+ +
+
+

Sell Your Domains

+

Marketplace

+
+

+ Create professional "For Sale" landing pages with one click. + DNS verification proves ownership. + Buyers contact you directly through Pounce. +

+
    +
  • +
    + +
    + Verified Owner badge +
  • +
  • +
    + +
    + Pounce Score valuation +
  • +
  • +
    + +
    + Secure contact form +
  • +
+ + Browse Marketplace + +
-

- Create professional "For Sale" landing pages with one click. - DNS verification proves ownership. - Buyers contact you directly through Pounce. -

-
    -
  • - - Verified Owner badge -
  • -
  • - - Pounce Score valuation -
  • -
  • - - Secure contact form -
  • -
- - Browse Marketplace - -
{/* Sniper Alerts */} -
-
-
- -
-
-

Sniper Alerts

-

Hyper-Personalized

-
+
+ {/* Decorative element */} +
+
+
+
+
+ +
+
+
+ +
+
+

Sniper Alerts

+

Hyper-Personalized

+
+
+

+ Ultra-specific filters that notify you exactly when matching domains appear. + "4-letter .com under $500 without numbers" — we've got you. +

+
    +
  • +
    + +
    + Custom TLD, length, price filters +
  • +
  • +
    + +
    + Email & SMS alerts +
  • +
  • +
    + +
    + Real-time auction matching +
  • +
+ + Set Up Alerts + +
-

- Ultra-specific filters that notify you exactly when matching domains appear. - "4-letter .com under $500 without numbers" — we've got you. -

-
    -
  • - - Custom TLD, length, price filters -
  • -
  • - - Email & SMS alerts -
  • -
  • - - Real-time auction matching -
  • -
- - Set Up Alerts - -
+ + {/* Transition to TLDs */} +
+
+
{/* Trending TLDs Section */}