From 9f35eaadf6754c4fa912b78fbdd301ae24ddad8b Mon Sep 17 00:00:00 2001 From: Kurdistan Tech Ministry Date: Tue, 24 Feb 2026 03:47:03 +0300 Subject: [PATCH] feat: compact OKX-style mobile P2P ad cards --- web/src/components/p2p/AdList.tsx | 92 +++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/web/src/components/p2p/AdList.tsx b/web/src/components/p2p/AdList.tsx index 2ca3d0b3..5ae85c3c 100644 --- a/web/src/components/p2p/AdList.tsx +++ b/web/src/components/p2p/AdList.tsx @@ -7,7 +7,7 @@ import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Loader2, Shield, Zap } from 'lucide-react'; import { useP2PIdentity } from '@/contexts/P2PIdentityContext'; import { TradeModal } from './TradeModal'; -import { MerchantTierBadge } from './MerchantTierBadge'; +import { MerchantTierBadge, MerchantTierIcon } from './MerchantTierBadge'; import { getUserReputation, type P2PFiatOffer, type P2PReputation } from '@shared/lib/p2p-fiat'; import { supabase } from '@/lib/supabase'; import type { P2PFilters } from './types'; @@ -193,11 +193,92 @@ export function AdList({ type, filters }: AdListProps) { } return ( -
+
{offers.map(offer => ( - -
+ {/* Mobile Compact Layout — OKX style */} + + {/* Row 1: Avatar + wallet + badges | trade stats */} +
+ + + {offer.seller_wallet.slice(0, 2).toUpperCase()} + + +
+ + {offer.seller_wallet.slice(0, 6)}...{offer.seller_wallet.slice(-4)} + + {offer.merchant_tier && ( + + )} + {offer.seller_reputation?.verified_merchant && ( + + )} + {offer.seller_reputation?.fast_trader && ( + + )} +
+ {offer.seller_reputation && ( + + {offer.seller_reputation.completed_trades} {t('p2p.tradesShort', { defaultValue: 'trades' })} · {((offer.seller_reputation.completed_trades / (offer.seller_reputation.total_trades || 1)) * 100).toFixed(0)}% + + )} +
+ + {/* Row 2: Price | Available amount | Min limit */} +
+ + {offer.price_per_unit.toFixed(2)} {offer.fiat_currency} + + + {offer.remaining_amount} {offer.token} + + + Min: {offer.min_order_amount || 0} {offer.token} + +
+ + {/* Row 3: Payment method | Time limit | Action button */} +
+ + {offer.payment_method_name || t('p2p.na')} + + + {offer.time_limit_minutes} min + + {offer.seller_id === userId && type !== 'my-ads' ? ( + + {t('p2pAd.yourAd')} + + ) : ( + + )} +
+ + {/* Status badge for my-ads */} + {type === 'my-ads' && ( +
+ + {offer.status.toUpperCase()} + + + {new Date(offer.created_at).toLocaleDateString()} + +
+ )} +
+ + {/* Desktop Layout */} + +
{/* Seller Info */}
@@ -271,7 +352,6 @@ export function AdList({ type, filters }: AdListProps) {