import { useState, useEffect, useCallback } from 'react'; import { Star, Clock, ChevronDown, Loader2 } from 'lucide-react'; import { cn } from '@/lib/utils'; import { useAuth } from '@/contexts/AuthContext'; import { useTranslation } from '@/i18n'; import { useTelegram } from '@/hooks/useTelegram'; import { getP2POffers, type P2POffer } from '@/lib/p2p-api'; interface OfferListProps { adType: 'buy' | 'sell'; onAcceptOffer: (offer: P2POffer) => void; } const FIAT_CURRENCIES = ['TRY', 'IQD', 'IRR', 'EUR', 'USD']; const TOKENS = ['HEZ', 'PEZ']; export function OfferList({ adType, onAcceptOffer }: OfferListProps) { const { sessionToken } = useAuth(); const { t, isRTL } = useTranslation(); const { hapticImpact } = useTelegram(); const [offers, setOffers] = useState([]); const [loading, setLoading] = useState(true); const [page, setPage] = useState(1); const [total, setTotal] = useState(0); const [selectedCurrency, setSelectedCurrency] = useState(''); const [selectedToken, setSelectedToken] = useState(''); const [showFilters, setShowFilters] = useState(false); const limit = 20; const fetchOffers = useCallback( async (p = 1) => { if (!sessionToken) return; setLoading(true); try { const result = await getP2POffers({ sessionToken, adType, token: selectedToken || undefined, fiatCurrency: selectedCurrency || undefined, page: p, limit, }); setOffers(result.offers); setTotal(result.total); setPage(p); } catch (err) { console.error('Failed to fetch offers:', err); } finally { setLoading(false); } }, [sessionToken, adType, selectedToken, selectedCurrency] ); useEffect(() => { fetchOffers(1); }, [fetchOffers]); const handleAccept = (offer: P2POffer) => { hapticImpact('medium'); onAcceptOffer(offer); }; const totalPages = Math.ceil(total / limit); return (
{/* Filters Toggle */} {showFilters && (
)} {/* Offer List */} {loading ? (
) : offers.length === 0 ? (

{t('p2p.noOffers')}

) : (
{offers.map((offer) => (
{/* Top: Token + Price */}
{offer.token} / {offer.fiat_currency}
{offer.price_per_unit?.toLocaleString(undefined, { maximumFractionDigits: 2 })}{' '} {offer.fiat_currency}
{/* Middle: Amount + Limits */}
{t('p2p.available')}: {offer.remaining_amount} {offer.token} {offer.min_order_amount && `${t('p2p.min')}: ${offer.min_order_amount}`} {offer.min_order_amount && offer.max_order_amount && ' - '} {offer.max_order_amount && `${t('p2p.max')}: ${offer.max_order_amount}`}
{/* Bottom: Reputation + Payment + Action */}
{offer.seller_reputation && ( {offer.seller_reputation.completed_trades} {t('p2p.trades')} )} {offer.payment_method_name && ( {offer.payment_method_name} )} {offer.time_limit_minutes}m
))} {/* Pagination */} {totalPages > 1 && (
{page} / {totalPages}
)}
)}
); }