'use client' import { useEffect, useMemo, useState, useCallback } from 'react' import { useSearchParams } from 'next/navigation' import { useStore } from '@/lib/store' import { api } from '@/lib/api' import { Sidebar } from '@/components/Sidebar' import { Loader2, MessageSquare, X, Send, Lock, Target, Gavel, Eye, TrendingUp, Menu, Settings, LogOut, Crown, Zap, } from 'lucide-react' import Link from 'next/link' import Image from 'next/image' import clsx from 'clsx' type Thread = { id: number listing_id: number domain: string slug: string status: string created_at: string closed_at: string | null closed_reason: string | null } type Message = { id: number inquiry_id: number listing_id: number sender_user_id: number body: string created_at: string } export default function InboxPage() { const { user, subscription, logout, checkAuth } = useStore() const searchParams = useSearchParams() const openInquiryId = searchParams.get('inquiry') const [threads, setThreads] = useState([]) const [loading, setLoading] = useState(true) const [menuOpen, setMenuOpen] = useState(false) const [activeThread, setActiveThread] = useState(null) const [messages, setMessages] = useState([]) const [loadingMessages, setLoadingMessages] = useState(false) const [sending, setSending] = useState(false) const [draft, setDraft] = useState('') const [error, setError] = useState(null) useEffect(() => { checkAuth() }, [checkAuth]) const tierName = subscription?.tier_name || subscription?.tier || 'Scout' const TierIcon = tierName === 'Tycoon' ? Crown : tierName === 'Trader' ? TrendingUp : Zap const drawerNavSections = [ { title: 'Discover', items: [ { href: '/terminal/hunt', label: 'Radar', icon: Target }, { href: '/terminal/market', label: 'Market', icon: Gavel }, { href: '/terminal/intel', label: 'Intel', icon: TrendingUp }, ]}, { title: 'Manage', items: [ { href: '/terminal/watchlist', label: 'Watchlist', icon: Eye }, { href: '/terminal/inbox', label: 'Inbox', icon: MessageSquare, active: true }, ]}, ] const loadThreads = useCallback(async () => { setLoading(true) setError(null) try { const data = await api.getMyInquiryThreads() setThreads(data) } catch (err: any) { setError(err?.message || 'Failed to load inbox') } finally { setLoading(false) } }, []) useEffect(() => { loadThreads() }, [loadThreads]) const threadsById = useMemo(() => { const map = new Map() threads.forEach(t => map.set(t.id, t)) return map }, [threads]) useEffect(() => { if (!openInquiryId) return const id = Number(openInquiryId) if (!Number.isFinite(id)) return const t = threadsById.get(id) if (t) setActiveThread(t) }, [openInquiryId, threadsById]) const loadMessages = useCallback(async (thread: Thread) => { setLoadingMessages(true) setError(null) try { const data = await api.getInquiryMessagesAsBuyer(thread.id) setMessages(data) } catch (err: any) { setError(err?.message || 'Failed to load messages') } finally { setLoadingMessages(false) } }, []) useEffect(() => { if (!activeThread) return loadMessages(activeThread) }, [activeThread, loadMessages]) const sendMessage = useCallback(async () => { if (!activeThread) return const body = draft.trim() if (!body) return setSending(true) setError(null) try { const created = await api.sendInquiryMessageAsBuyer(activeThread.id, body) setDraft('') setMessages(prev => [...prev, created]) } catch (err: any) { setError(err?.message || 'Failed to send') } finally { setSending(false) } }, [activeThread, draft]) return (
{/* MOBILE HEADER */}
Inbox
{/* DESKTOP HEADER */}
Inbox

Inbox

Your inquiry threads with verified sellers.

{loading ? (
) : error ? (
{error}
) : threads.length === 0 ? (

No threads yet

Browse Pounce Direct deals and send an inquiry.

View Deals
) : (
{/* Thread list */}
Threads
{threads.map(t => ( ))}
{/* Thread detail */}
{!activeThread ? (
Select a thread
) : ( <>
Thread
{activeThread.domain}
View Deal
{loadingMessages ? (
) : messages.length === 0 ? (
No messages
) : ( messages.map(m => (
{m.sender_user_id === user?.id ? 'You' : 'Seller'} {new Date(m.created_at).toLocaleString('en-US')}
{m.body}
)) )}
{activeThread.status === 'closed' || activeThread.status === 'spam' ? (
Thread is closed.
) : (