import React, { useEffect, useState } from 'react' import { FaCreditCard, FaLock, FaArrowLeft, FaCalendarAlt, FaClock } from 'react-icons/fa' import { BillingCycle, BasketItem, InstallmentOptionDto, PaymentMethodDto, } from '@/proxy/order/models' import { OrderService } from '@/services/order.service' import { CustomTenantDto } from '@/proxy/config/models' import { useLocalization } from '@/utils/hooks/useLocalization' import { Button } from '@/components/ui' interface BasketData { items: BasketItem[] subtotal: number vatTotal: number total: number globalBillingCycle: BillingCycle globalPeriod: number } interface PaymentFormProps { tenant: CustomTenantDto onBack: () => void onComplete: (paymentData: Record) => void basketData: BasketData } export const PaymentForm: React.FC = ({ onBack, onComplete, basketData }) => { const defaultPaymentMethod = 'CreditCard' const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(defaultPaymentMethod) const [selectedInstallment, setSelectedInstallment] = useState() const [paymentData, setPaymentData] = useState({ cardNumber: '', expiryDate: '', cvv: '', cardName: '', }) const [licenseStartTime, setLicenseStartTime] = useState(() => new Date().toISOString().slice(0, 10), ) const { translate } = useLocalization() const [paymentMethods, setPaymentMethods] = useState([]) const [installmentOptions, setInstallmentOptions] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const fetchData = async () => { const orderService = new OrderService() try { const paymentResponse = await orderService.getPaymentMethodList() setPaymentMethods(paymentResponse.data) if (paymentResponse.data.length > 0) { setSelectedPaymentMethod(paymentResponse.data[1].name) } const installmentResponse = await orderService.getInstallmentOptionList() setInstallmentOptions(installmentResponse.data) } catch (err) { console.error('Ödeme şekilleri ve Komisyon Bilgileri alınamadı', err) } finally { setLoading(false) } } fetchData() }, []) const selectedMethod = paymentMethods.find((m) => m.name === selectedPaymentMethod) let commission = 0 if (selectedPaymentMethod === defaultPaymentMethod && selectedInstallment) { commission = basketData.total * selectedInstallment.commission } else if (selectedMethod) { commission = basketData.total * selectedMethod.commission } const finalTotal = basketData.total + commission const period = basketData.globalPeriod > 0 ? basketData.globalPeriod : 1 const billingCycle = basketData.globalBillingCycle || 'yearly' const licenseEndTime = calculateLicenseEndTime(new Date(licenseStartTime), billingCycle, period) const formatPrice = (price: number) => new Intl.NumberFormat('tr-TR', { style: 'currency', currency: 'TRY', minimumFractionDigits: 2, }).format(price) const vatRateLabel = (() => { const rates = Array.from( new Set(basketData.items.map((item) => Math.round((item.vatRate ?? 0) * 100))), ).filter((rate) => rate > 0) return rates.length > 0 ? ` (${rates.map((rate) => `%${rate}`).join(', ')})` : '' })() const handleSubmit = (e: React.FormEvent) => { e.preventDefault() onComplete({ ...paymentData, licenseStartTime: new Date(licenseStartTime).toISOString(), licenseEndTime: licenseEndTime.toISOString(), paymentMethodId: selectedMethod?.id, installment: selectedPaymentMethod === defaultPaymentMethod ? (selectedInstallment?.installment ?? 1) : 1, commission, total: finalTotal, }) } const handleInputChange = (field: string, value: string) => { setPaymentData((prev) => ({ ...prev, [field]: value })) } function calculateLicenseEndTime( startTime: Date, selectedBillingCycle: string, selectedPeriod: number, ) { const stopTime = new Date(startTime) if (selectedBillingCycle === 'monthly') { stopTime.setMonth(stopTime.getMonth() + selectedPeriod) } else { stopTime.setFullYear(stopTime.getFullYear() + selectedPeriod) } return stopTime } const formatDate = (date: Date) => new Intl.DateTimeFormat('tr-TR', { day: '2-digit', month: '2-digit', year: 'numeric', }).format(date) const billingCycleLabel = billingCycle === 'monthly' ? translate('::Public.products.billingcycle.monthly') : billingCycle === 'yearly' ? translate('::Public.products.billingcycle.yearly') : '-' return (
{loading ? (
{translate('::App.Loading')}
) : (
{/* 3 Sütun: Ödeme Yöntemi | Taksit Seçenekleri | Sipariş Özeti */}

Lisans Bilgileri

setLicenseStartTime(e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
Period {period}
Billing Cycle {billingCycleLabel}
License End Time {formatDate(licenseEndTime)}
{/* 1. Sütun: Ödeme Yöntemi */}

{' '} {translate('::Public.payment.method.title')}

{paymentMethods.map((method) => ( ))}
{/* Taksit Seçenekleri */} {selectedPaymentMethod === defaultPaymentMethod && (

{translate('::App.Orders.InstallmentOptions')}

{installmentOptions.map((option) => ( ))}
)}
{/* 3. Sütun: Kart Bilgileri + Sipariş Özeti ve Butonlar */}
{/* Kart Bilgileri */} {selectedPaymentMethod === defaultPaymentMethod && (

{translate('::Public.payment.card.title')}

handleInputChange('cardName', e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400" placeholder={translate('::Public.payment.card.name')} /> handleInputChange('cardNumber', e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400" placeholder={translate('::Public.payment.card.number')} maxLength={19} />
handleInputChange('expiryDate', e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400" placeholder="MM/YY" maxLength={5} /> handleInputChange('cvv', e.target.value)} className="w-full px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400" placeholder="CVV" maxLength={4} />
)} {/* Sipariş Özeti ve Butonlar */}

{translate('::Public.payment.summary.title')}

{basketData.items.map((item, index) => (
{item.product.imageUrl && ( {translate('::' )}
{translate('::' + item.product.name)}
{item.product.isQuantityBased && (
x {item.quantity}
)}
{formatPrice(item.totalPrice)}
))}
{translate('::Public.payment.summary.subtotal')} {formatPrice(basketData.subtotal)}
{translate('::Public.products.kdv')} {vatRateLabel} {formatPrice(basketData.vatTotal)}
{translate('::Public.payment.installments.commission')} {formatPrice(commission)}
{selectedPaymentMethod === defaultPaymentMethod && selectedInstallment?.installment && selectedInstallment.installment > 1 && (
{translate('::Public.payment.summary.monthlyInstallment')}: {formatPrice(finalTotal / selectedInstallment.installment)} x{' '} {selectedInstallment.installment}
)}
{translate('::App.Listform.ListformField.Total')} {formatPrice(finalTotal)}
{/* Butonlar */}
)}
) }