import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { usePezkuwi } from '@/contexts/PezkuwiContext'; import { useP2PIdentity } from '@/contexts/P2PIdentityContext'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { toast } from 'sonner'; import { Loader2 } from 'lucide-react'; import { createFiatOffer, getPaymentMethods, validatePaymentDetails, type PaymentMethod, type FiatCurrency, type CryptoToken } from '@shared/lib/p2p-fiat'; interface CreateAdProps { onAdCreated: () => void; } export function CreateAd({ onAdCreated }: CreateAdProps) { const { t } = useTranslation(); const { selectedAccount } = usePezkuwi(); const { userId } = useP2PIdentity(); const [paymentMethods, setPaymentMethods] = useState([]); const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(null); const [loading, setLoading] = useState(false); // Form fields const [adType, setAdType] = useState<'buy' | 'sell'>('sell'); const [token, setToken] = useState('HEZ'); const [amountCrypto, setAmountCrypto] = useState(''); const [fiatCurrency, setFiatCurrency] = useState('TRY'); const [fiatAmount, setFiatAmount] = useState(''); const [paymentDetails, setPaymentDetails] = useState>({}); const [timeLimit, setTimeLimit] = useState(30); const [minOrderAmount, setMinOrderAmount] = useState(''); const [maxOrderAmount, setMaxOrderAmount] = useState(''); // Load payment methods when currency changes useEffect(() => { const loadPaymentMethods = async () => { const methods = await getPaymentMethods(fiatCurrency); setPaymentMethods(methods); setSelectedPaymentMethod(null); setPaymentDetails({}); }; loadPaymentMethods(); }, [fiatCurrency]); // Calculate price per unit const pricePerUnit = amountCrypto && fiatAmount ? (parseFloat(fiatAmount) / parseFloat(amountCrypto)).toFixed(2) : '0'; const handlePaymentMethodChange = (methodId: string) => { const method = paymentMethods.find(m => m.id === methodId); setSelectedPaymentMethod(method || null); // Initialize payment details with empty values if (method) { const initialDetails: Record = {}; Object.keys(method.fields).forEach(field => { initialDetails[field] = ''; }); setPaymentDetails(initialDetails); } }; const handlePaymentDetailChange = (field: string, value: string) => { setPaymentDetails(prev => ({ ...prev, [field]: value })); }; const handleCreateAd = async () => { if (!selectedAccount || !userId) { toast.error(t('p2p.connectWalletAndLogin')); return; } if (!selectedPaymentMethod) { toast.error(t('p2pCreate.selectPaymentMethodError')); return; } // Validate payment details const validation = validatePaymentDetails( paymentDetails, selectedPaymentMethod.validation_rules ); if (!validation.valid) { const firstError = Object.values(validation.errors)[0]; toast.error(firstError); return; } // Validate amounts const cryptoAmt = parseFloat(amountCrypto); const fiatAmt = parseFloat(fiatAmount); if (!cryptoAmt || cryptoAmt <= 0) { toast.error(t('p2pCreate.invalidCryptoAmount')); return; } if (!fiatAmt || fiatAmt <= 0) { toast.error(t('p2pCreate.invalidFiatAmount')); return; } if (selectedPaymentMethod.min_trade_amount && fiatAmt < selectedPaymentMethod.min_trade_amount) { toast.error(t('p2pCreate.minTradeAmount', { amount: selectedPaymentMethod.min_trade_amount, currency: fiatCurrency })); return; } if (selectedPaymentMethod.max_trade_amount && fiatAmt > selectedPaymentMethod.max_trade_amount) { toast.error(t('p2pCreate.maxTradeAmount', { amount: selectedPaymentMethod.max_trade_amount, currency: fiatCurrency })); return; } setLoading(true); try { await createFiatOffer({ userId, sellerWallet: selectedAccount.address, token, amountCrypto: cryptoAmt, fiatCurrency, fiatAmount: fiatAmt, paymentMethodId: selectedPaymentMethod.id, paymentDetails, timeLimitMinutes: timeLimit, minOrderAmount: minOrderAmount ? parseFloat(minOrderAmount) : undefined, maxOrderAmount: maxOrderAmount ? parseFloat(maxOrderAmount) : undefined, adType, }); onAdCreated(); } catch (error) { if (import.meta.env.DEV) console.error('Create ad error:', error); toast.error(t('p2pCreate.failedToCreate')); } finally { setLoading(false); } }; return ( {t('p2pCreate.title')} {t('p2pCreate.description')} {/* Ad Type Selection */}

{adType === 'sell' ? t('p2pCreate.sellDescription') : t('p2pCreate.buyDescription')}

{/* Crypto Details */}
setAmountCrypto(e.target.value)} placeholder={t('p2pCreate.amountPlaceholder')} className="placeholder:text-gray-500 placeholder:opacity-50" />
{/* Fiat Details */}
setFiatAmount(e.target.value)} placeholder={t('p2pCreate.amountPlaceholder')} className="placeholder:text-gray-500 placeholder:opacity-50" />
{/* Price Display */} {amountCrypto && fiatAmount && (

{t('p2pCreate.pricePerToken', { token })}

{pricePerUnit} {fiatCurrency}

)} {/* Payment Method */}
{/* Dynamic Payment Details Fields */} {selectedPaymentMethod && Object.keys(selectedPaymentMethod.fields).length > 0 && (

{t('p2pCreate.paymentDetails')}

{Object.entries(selectedPaymentMethod.fields).map(([field, placeholder]) => (
handlePaymentDetailChange(field, e.target.value)} placeholder={placeholder} className="placeholder:text-gray-500 placeholder:opacity-50" />
))}
)} {/* Order Limits */}
setMinOrderAmount(e.target.value)} placeholder={t('p2pCreate.minOrderPlaceholder')} className="placeholder:text-gray-500 placeholder:opacity-50" />
setMaxOrderAmount(e.target.value)} placeholder={t('p2pCreate.maxOrderPlaceholder')} className="placeholder:text-gray-500 placeholder:opacity-50" />
{/* Time Limit */}
); }