"use client" import { useState, useRef } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Lock, ShieldCheck, Landmark } from "lucide-react" interface Props { amount: number eventName: string organizationName: string eventId: string qrSourceId: string | null onComplete: (identity: { donorName: string donorEmail: string donorPhone: string giftAid: boolean }) => void } function formatSortCode(value: string): string { const digits = value.replace(/\D/g, "").slice(0, 6) if (digits.length > 4) return digits.slice(0, 2) + "-" + digits.slice(2, 4) + "-" + digits.slice(4) if (digits.length > 2) return digits.slice(0, 2) + "-" + digits.slice(2) return digits } type Phase = "form" | "reviewing" | "processing" export function DirectDebitStep({ amount, eventName, organizationName, eventId, qrSourceId, onComplete }: Props) { const [phase, setPhase] = useState("form") const [accountName, setAccountName] = useState("") const [email, setEmail] = useState("") const [sortCode, setSortCode] = useState("") const [accountNumber, setAccountNumber] = useState("") const [giftAid, setGiftAid] = useState(false) const [mandateAgreed, setMandateAgreed] = useState(false) const [errors, setErrors] = useState>({}) const accountNumberRef = useRef(null) const pounds = (amount / 100).toFixed(2) const validate = (): boolean => { const errs: Record = {} if (!accountName.trim()) errs.accountName = "Account holder name required" if (!email.includes("@")) errs.email = "Valid email required" const scDigits = sortCode.replace(/\D/g, "") if (scDigits.length !== 6) errs.sortCode = "Sort code must be 6 digits" const anDigits = accountNumber.replace(/\D/g, "") if (anDigits.length < 7 || anDigits.length > 8) errs.accountNumber = "Account number must be 7-8 digits" if (!mandateAgreed) errs.mandate = "You must agree to the Direct Debit mandate" setErrors(errs) return Object.keys(errs).length === 0 } const handleSortCodeChange = (value: string) => { const formatted = formatSortCode(value) setSortCode(formatted) // Auto-advance when complete if (formatted.replace(/\D/g, "").length === 6) { accountNumberRef.current?.focus() } } const handleReview = () => { if (!validate()) return setPhase("reviewing") } const handleConfirm = async () => { setPhase("processing") // Try real GoCardless flow first try { const res = await fetch("/api/gocardless/create-flow", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ amountPence: amount, donorName: accountName, donorEmail: email, donorPhone: "", giftAid, eventId, qrSourceId, }), }) const data = await res.json() if (data.mode === "live" && data.redirectUrl) { // Redirect to GoCardless hosted page window.location.href = data.redirectUrl return } // Simulated mode — fall through to onComplete } catch { // Fall through to simulated } // Simulated fallback await new Promise((r) => setTimeout(r, 1000)) onComplete({ donorName: accountName, donorEmail: email, donorPhone: "", giftAid, }) } // Processing phase if (phase === "processing") { return (

Setting Up Direct Debit

Creating your mandate with GoCardless...

This may take a few seconds.

) } // Review phase if (phase === "reviewing") { return (

Confirm Direct Debit

Please review your mandate details

{/* Summary card */}

Account Holder

{accountName}

Email

{email}

Sort Code

{sortCode}

Account Number

••••{accountNumber.slice(-4)}

Amount

£{pounds}

Payee

{organizationName}

{/* Guarantee box */}

Direct Debit Guarantee

This Guarantee is offered by all banks and building societies that accept instructions to pay Direct Debits. If there are any changes to the amount, date, or frequency of your Direct Debit, you will be notified in advance. If an error is made in the payment, you are entitled to a full and immediate refund from your bank. You can cancel a Direct Debit at any time by contacting your bank.

Processed securely by GoCardless
) } // Form phase (default) return (

Set Up Direct Debit

Pledge: £{pounds}{" "} for {eventName}

{/* Info banner */}

How it works

We'll set up a Direct Debit mandate via GoCardless. The payment will be collected automatically in 3-5 working days. You can cancel anytime.

{/* Bank details form */}
setAccountName(e.target.value)} autoComplete="name" className={errors.accountName ? "border-red-500" : ""} /> {errors.accountName &&

{errors.accountName}

}
setEmail(e.target.value)} autoComplete="email" inputMode="email" className={errors.email ? "border-red-500" : ""} /> {errors.email &&

{errors.email}

}
handleSortCodeChange(e.target.value)} inputMode="numeric" maxLength={8} className={`font-mono text-base ${errors.sortCode ? "border-red-500" : ""}`} /> {errors.sortCode &&

{errors.sortCode}

}
setAccountNumber(e.target.value.replace(/\D/g, "").slice(0, 8))} inputMode="numeric" maxLength={8} className={`font-mono text-base ${errors.accountNumber ? "border-red-500" : ""}`} /> {errors.accountNumber &&

{errors.accountNumber}

}
{/* Gift Aid */} {/* Direct Debit mandate agreement */} {errors.mandate &&

{errors.mandate}

} {/* DD Guarantee mini */}

Protected by the Direct Debit Guarantee. You can cancel anytime by contacting your bank. Full refund if any errors occur.

Processed securely by GoCardless
) }