'use client' import { useEffect, useState } from 'react' import { useSearchParams } from 'next/navigation' import { useStore } from '@/lib/store' import { api } from '@/lib/api' import { CommandCenterLayout } from '@/components/CommandCenterLayout' import { PageContainer, StatCard, Badge } from '@/components/PremiumTable' import { Plus, Shield, Eye, MessageSquare, ExternalLink, Loader2, Trash2, CheckCircle, AlertCircle, Copy, RefreshCw, DollarSign, X, Sparkles, Tag, Store, } from 'lucide-react' import Link from 'next/link' import clsx from 'clsx' interface Listing { id: number domain: string slug: string title: string | null description: string | null asking_price: number | null min_offer: number | null currency: string price_type: string pounce_score: number | null estimated_value: number | null verification_status: string is_verified: boolean status: string show_valuation: boolean allow_offers: boolean view_count: number inquiry_count: number public_url: string created_at: string published_at: string | null } interface VerificationInfo { verification_code: string dns_record_type: string dns_record_name: string dns_record_value: string instructions: string status: string } export default function MyListingsPage() { const { subscription } = useStore() const searchParams = useSearchParams() const prefillDomain = searchParams.get('domain') const [listings, setListings] = useState([]) const [loading, setLoading] = useState(true) // Modals - auto-open if domain is prefilled const [showCreateModal, setShowCreateModal] = useState(false) const [showVerifyModal, setShowVerifyModal] = useState(false) const [selectedListing, setSelectedListing] = useState(null) const [verificationInfo, setVerificationInfo] = useState(null) const [verifying, setVerifying] = useState(false) const [creating, setCreating] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) // Create form const [newListing, setNewListing] = useState({ domain: '', title: '', description: '', asking_price: '', price_type: 'negotiable', allow_offers: true, }) useEffect(() => { loadListings() }, []) // Auto-open create modal if domain is prefilled from portfolio useEffect(() => { if (prefillDomain) { setNewListing(prev => ({ ...prev, domain: prefillDomain })) setShowCreateModal(true) } }, [prefillDomain]) const loadListings = async () => { setLoading(true) try { const data = await api.request('/listings/my') setListings(data) } catch (err: any) { console.error('Failed to load listings:', err) } finally { setLoading(false) } } const handleCreate = async (e: React.FormEvent) => { e.preventDefault() setCreating(true) setError(null) try { await api.request('/listings', { method: 'POST', body: JSON.stringify({ domain: newListing.domain, title: newListing.title || null, description: newListing.description || null, asking_price: newListing.asking_price ? parseFloat(newListing.asking_price) : null, price_type: newListing.price_type, allow_offers: newListing.allow_offers, }), }) setSuccess('Listing created! Now verify ownership to publish.') setShowCreateModal(false) setNewListing({ domain: '', title: '', description: '', asking_price: '', price_type: 'negotiable', allow_offers: true }) loadListings() } catch (err: any) { setError(err.message) } finally { setCreating(false) } } const handleStartVerification = async (listing: Listing) => { setSelectedListing(listing) setVerifying(true) try { const info = await api.request(`/listings/${listing.id}/verify-dns`, { method: 'POST', }) setVerificationInfo(info) setShowVerifyModal(true) } catch (err: any) { setError(err.message) } finally { setVerifying(false) } } const handleCheckVerification = async () => { if (!selectedListing) return setVerifying(true) try { const result = await api.request<{ verified: boolean; message: string }>( `/listings/${selectedListing.id}/verify-dns/check` ) if (result.verified) { setSuccess('Domain verified! You can now publish your listing.') setShowVerifyModal(false) loadListings() } else { setError(result.message) } } catch (err: any) { setError(err.message) } finally { setVerifying(false) } } const handlePublish = async (listing: Listing) => { try { await api.request(`/listings/${listing.id}`, { method: 'PUT', body: JSON.stringify({ status: 'active' }), }) setSuccess('Listing published!') loadListings() } catch (err: any) { setError(err.message) } } const handleDelete = async (listing: Listing) => { if (!confirm(`Delete listing for ${listing.domain}?`)) return try { await api.request(`/listings/${listing.id}`, { method: 'DELETE' }) setSuccess('Listing deleted') loadListings() } catch (err: any) { setError(err.message) } } const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text) setSuccess('Copied to clipboard!') } const formatPrice = (price: number | null, currency: string) => { if (!price) return 'Make Offer' return new Intl.NumberFormat('en-US', { style: 'currency', currency, minimumFractionDigits: 0, }).format(price) } const getStatusBadge = (status: string, isVerified: boolean) => { if (status === 'active') return Live if (status === 'draft' && !isVerified) return Needs Verification if (status === 'draft') return Draft if (status === 'sold') return Sold return {status} } const tier = subscription?.tier || 'scout' const limits = { scout: 2, trader: 10, tycoon: 50 } const maxListings = limits[tier as keyof typeof limits] || 2 return ( Browse Marketplace } > {/* Messages */} {error && (

{error}

)} {success && (

{success}

)} {/* Stats */}
l.status === 'active').length} icon={CheckCircle} accent /> sum + l.view_count, 0)} icon={Eye} /> sum + l.inquiry_count, 0)} icon={MessageSquare} />
{/* Listings */} {loading ? (
) : listings.length === 0 ? (

No Listings Yet

Create your first listing to sell a domain on the Pounce marketplace.

) : (
{listings.map((listing) => (
{/* Domain Info */}

{listing.domain}

{getStatusBadge(listing.status, listing.is_verified)} {listing.is_verified && (
)}
{listing.title && (

{listing.title}

)}
{/* Price */}

{formatPrice(listing.asking_price, listing.currency)}

{listing.pounce_score && (

Score: {listing.pounce_score}

)}
{/* Stats */}
{listing.view_count} {listing.inquiry_count}
{/* Actions */}
{!listing.is_verified && ( )} {listing.is_verified && listing.status === 'draft' && ( )} {listing.status === 'active' && ( View )}
))}
)}
{/* Create Modal */} {showCreateModal && (

List Domain for Sale

setNewListing({ ...newListing, domain: e.target.value })} placeholder="example.com" className="w-full px-4 py-3 bg-background border border-border rounded-xl text-foreground placeholder:text-foreground-subtle focus:outline-none focus:border-accent" />
setNewListing({ ...newListing, title: e.target.value })} placeholder="Perfect for AI startups" className="w-full px-4 py-3 bg-background border border-border rounded-xl text-foreground placeholder:text-foreground-subtle focus:outline-none focus:border-accent" />