import { useEffect, useRef, useState } from "preact/hooks"; import { encryptDataWithStoredPassword, getEncryptionPassword, } from "../../helpers.ts"; interface AddPaymentMethodDialogProps { onClose: () => void; userId?: string; } type FieldErrorState = { bank_name: boolean; account_type: boolean; routing_number: boolean; account_number: boolean; }; export default function AddPaymentMethodDialog( { onClose, userId }: AddPaymentMethodDialogProps, ) { const formRef = useRef(null); const firstInputRef = useRef(null); const [loading, setLoading] = useState(false); const [fieldErrors, setFieldErrors] = useState({ bank_name: false, account_type: false, routing_number: false, account_number: false, }); useEffect(() => { // Focus first input when dialog opens setTimeout(() => { firstInputRef.current?.focus(); }, 100); }, []); const clearFieldError = (field: keyof FieldErrorState) => { setFieldErrors((prev) => ({ ...prev, [field]: false })); }; const getInputErrorClass = (hasError: boolean) => { return hasError ? "border-red-500 focus:border-red-500" : ""; }; const addNewPaymentMethod = async () => { if (!formRef.current) return; // Collect form data const formData = new FormData(formRef.current); const bankName = formData.get("bank_name")?.toString().trim() || ""; const accountType = formData.get("account_type")?.toString() || ""; const routingNumber = formData.get("routing_number")?.toString().trim() || ""; const accountNumber = formData.get("account_number")?.toString().trim() || ""; const isDefault = formData.get("is_default") === "true"; const sender = typeof location !== "undefined" ? location.pathname : "/"; const validation = { bank_name: !bankName, account_type: !accountType, routing_number: !routingNumber || routingNumber.length !== 9, account_number: !accountNumber || accountNumber.length < 4, }; setFieldErrors(validation); if ( validation.bank_name || validation.account_type || validation.routing_number || validation.account_number ) { return; } setLoading(true); localStorage.setItem("lock-route", "/tenant/payment-methods?modal=off"); // Build submission data const submitData = new FormData(); submitData.set("sender", sender); submitData.set("bank_name", bankName); submitData.set("account_type", accountType); submitData.set("is_default", isDefault ? "true" : "false"); // Encrypt sensitive fields if password is available const encryptionPassword = userId ? getEncryptionPassword(userId) : null; if (encryptionPassword && (routingNumber || accountNumber)) { try { // Encrypt routing number const encryptedRoutingNumber = await encryptDataWithStoredPassword( userId!, routingNumber, ); // Encrypt account number const encryptedAccountNumber = await encryptDataWithStoredPassword( userId!, accountNumber, ); if (encryptedRoutingNumber && encryptedAccountNumber) { submitData.set("routing_number_encrypted", encryptedRoutingNumber); submitData.set("account_number_encrypted", encryptedAccountNumber); // Send empty plaintext when encrypted submitData.set("routing_number", ""); submitData.set("account_number", ""); } else { throw new Error("Encryption returned empty result"); } } catch (error) { console.error("Encryption failed:", error); alert("Failed to encrypt payment method data. Please try again."); setLoading(false); return; } } else { // No encryption available, send plaintext (not recommended for production) console.warn("No encryption password available, sending plaintext"); submitData.set("routing_number", routingNumber); submitData.set("account_number", accountNumber); } // Submit the form try { const response = await fetch("/api/create/payment_method", { method: "POST", body: submitData, }); const data = await response.json(); if (data.success) { // Redirect to payment methods page globalThis.location.href = "/tenant/payment-methods"; } else { console.error("Failed to add payment method:", data.error); alert(data.error || "Failed to add payment method. Please try again."); setLoading(false); } } catch (error) { console.error("Error adding payment method:", error); alert("Failed to add payment method. Please try again."); setLoading(false); } }; return (

Add Payment Method

clearFieldError("bank_name")} />
Bank name is required.
Account type is required.
clearFieldError("routing_number")} />
Routing number must be 9 digits.
clearFieldError("account_number")} />
Account number is required (min 4 digits).
); }