import toast from 'react-hot-toast'; import { PaymentOptionsConfig } from '@/lib/api'; import { CreditCardIcon, BanknotesIcon, BoltIcon, BuildingLibraryIcon, } from '@heroicons/react/24/outline'; import type { PaymentMethod, BookingResult } from '../_types'; // Paraguayan RUC: 5-8 digit base + "-" + 1 check digit (DV), e.g. 1234567-9 or 80012345-0 export const rucPattern = /^\d{5,8}-\d$/; /** Sanitize RUC input: digits and a single user-typed dash, max 10 chars. No dash is auto-inserted. */ export function formatRuc(value: string): string { const cleaned = value.replace(/[^\d-]/g, ''); const firstDash = cleaned.indexOf('-'); const oneDash = firstDash === -1 ? cleaned : cleaned.slice(0, firstDash + 1) + cleaned.slice(firstDash + 1).replace(/-/g, ''); return oneDash.slice(0, 10); } /** Truncate a long invoice string for display. */ export function truncateInvoice(invoice: string, chars: number = 20): string { if (invoice.length <= chars * 2) return invoice; return `${invoice.slice(0, chars)}...${invoice.slice(-chars)}`; } /** Copy a Lightning invoice to the clipboard with localized feedback. */ export function copyInvoiceToClipboard(invoice: string, locale: string): void { navigator.clipboard.writeText(invoice).then(() => { toast.success(locale === 'es' ? '¡Copiado!' : 'Copied!'); }).catch(() => { toast.error(locale === 'es' ? 'Error al copiar' : 'Failed to copy'); }); } export interface PaymentMethodOption { id: PaymentMethod; icon: typeof CreditCardIcon; label: string; description: string; badge?: string; } /** Build the list of selectable payment methods from the event config. */ export function buildPaymentMethods( paymentConfig: PaymentOptionsConfig | null, locale: string ): PaymentMethodOption[] { const paymentMethods: PaymentMethodOption[] = []; if (paymentConfig?.lightningEnabled) { paymentMethods.push({ id: 'lightning', icon: BoltIcon, label: 'Bitcoin Lightning', description: locale === 'es' ? 'Pago instantáneo con Bitcoin' : 'Instant payment with Bitcoin', badge: locale === 'es' ? 'Instantáneo' : 'Instant', }); } if (paymentConfig?.tpagoEnabled) { paymentMethods.push({ id: 'tpago', icon: CreditCardIcon, label: locale === 'es' ? 'TPago / Tarjetas de Crédito' : 'TPago / Credit Cards', description: locale === 'es' ? 'Pagá con tarjetas de crédito locales o internacionales' : 'Pay with local or international credit cards', badge: locale === 'es' ? 'Manual' : 'Manual', }); } if (paymentConfig?.bankTransferEnabled) { paymentMethods.push({ id: 'bank_transfer', icon: BuildingLibraryIcon, label: locale === 'es' ? 'Transferencia Bancaria Local' : 'Local Bank Transfer', description: locale === 'es' ? 'Pago por transferencia bancaria en Paraguay' : 'Pay via Paraguayan bank transfer', badge: locale === 'es' ? 'Manual' : 'Manual', }); } if (paymentConfig?.cashEnabled) { paymentMethods.push({ id: 'cash', icon: BanknotesIcon, label: locale === 'es' ? 'Efectivo en el Evento' : 'Cash at Event', description: locale === 'es' ? 'Paga cuando llegues al evento' : 'Pay when you arrive at the event', badge: locale === 'es' ? 'Manual' : 'Manual', }); } return paymentMethods; } export interface SuccessContent { title: string; description: string; iconColor: string; iconTextColor: string; } /** Resolve the success-screen copy based on the payment method used. */ export function getSuccessContent( bookingResult: BookingResult | null, locale: string, t: (key: string) => string ): SuccessContent { if (bookingResult?.paymentMethod === 'cash') { return { title: locale === 'es' ? '¡Reserva Recibida!' : 'Reservation Received!', description: locale === 'es' ? 'Tu lugar está reservado. El pago se realizará en el evento.' : 'Your spot is reserved. Payment will be collected at the event.', iconColor: 'bg-yellow-100', iconTextColor: 'text-yellow-600', }; } if (bookingResult?.paymentMethod === 'lightning') { // For Lightning, if we're on success step, payment was confirmed return { title: locale === 'es' ? '¡Pago Confirmado!' : 'Payment Confirmed!', description: locale === 'es' ? '¡Tu reserva está confirmada! Te esperamos en el evento.' : 'Your booking is confirmed! See you at the event.', iconColor: 'bg-green-100', iconTextColor: 'text-green-600', }; } return { title: t('booking.success.title'), description: t('booking.success.description'), iconColor: 'bg-green-100', iconTextColor: 'text-green-600', }; }