"use client" import { useState, useRef, useEffect } from "react" import { Button } from "@/components/ui/button" import { Gift, Shield, Sparkles, Phone, Mail, MapPin, ChevronDown } from "lucide-react" // --- HMRC Gift Aid declaration (exact model wording) --- const GIFT_AID_DECLARATION = "I am a UK taxpayer and understand that if I pay less Income Tax and/or Capital Gains Tax in the current tax year than the amount of Gift Aid claimed on all my donations in that tax year it is my responsibility to pay any difference." const EMAIL_CONSENT_TEXT = "I agree to receive email updates about this pledge, including payment reminders and receipts." const WHATSAPP_CONSENT_TEXT = "I agree to receive WhatsApp messages about this pledge, including payment reminders and receipts. Reply STOP to opt out." const CONSENT_VERSION = "v1" interface ConsentData { donorName: string donorEmail: string donorPhone: string donorAddressLine1: string donorPostcode: string giftAid: boolean isZakat: boolean emailOptIn: boolean whatsappOptIn: boolean consentMeta: { giftAid?: { declared: boolean; declarationText: string; declaredAt: string } email?: { granted: boolean; consentText: string; grantedAt: string } whatsapp?: { granted: boolean; consentText: string; grantedAt: string } consentVersion: string } } interface Props { onSubmit: (data: ConsentData) => void amount: number zakatEligible?: boolean orgName?: string } export function IdentityStep({ onSubmit, amount, zakatEligible, orgName }: Props) { const [name, setName] = useState("") const [email, setEmail] = useState("") const [phone, setPhone] = useState("") const [addressLine1, setAddressLine1] = useState("") const [postcode, setPostcode] = useState("") const [giftAid, setGiftAid] = useState(false) const [isZakat, setIsZakat] = useState(false) const [emailOptIn, setEmailOptIn] = useState(false) const [whatsappOptIn, setWhatsappOptIn] = useState(false) const [submitting, setSubmitting] = useState(false) const [showGiftAidAddress, setShowGiftAidAddress] = useState(false) const nameRef = useRef(null) useEffect(() => { nameRef.current?.focus() }, []) // When Gift Aid is toggled on, show address fields useEffect(() => { if (giftAid && !showGiftAidAddress) setShowGiftAidAddress(true) }, [giftAid, showGiftAidAddress]) // When Gift Aid is toggled off, clear address useEffect(() => { if (!giftAid) { setShowGiftAidAddress(false) setAddressLine1("") setPostcode("") } }, [giftAid]) const hasEmail = email.includes("@") const hasPhone = phone.length >= 10 const hasContact = hasEmail || hasPhone // Gift Aid requires: name + address + postcode + UK taxpayer declaration const giftAidValid = !giftAid || (name.length > 0 && addressLine1.length > 0 && postcode.length >= 5) const isValid = hasContact && giftAidValid const giftAidBonus = Math.round(amount * 0.25) const totalWithAid = amount + giftAidBonus const handleSubmit = async () => { if (!isValid) return setSubmitting(true) const now = new Date().toISOString() // Build immutable consent audit record const consentMeta: ConsentData["consentMeta"] = { consentVersion: CONSENT_VERSION, } if (giftAid) { consentMeta.giftAid = { declared: true, declarationText: GIFT_AID_DECLARATION, declaredAt: now, } } if (emailOptIn && hasEmail) { consentMeta.email = { granted: true, consentText: EMAIL_CONSENT_TEXT, grantedAt: now, } } if (whatsappOptIn && hasPhone) { consentMeta.whatsapp = { granted: true, consentText: WHATSAPP_CONSENT_TEXT, grantedAt: now, } } try { await onSubmit({ donorName: name, donorEmail: email, donorPhone: phone, donorAddressLine1: giftAid ? addressLine1 : "", donorPostcode: giftAid ? postcode : "", giftAid, isZakat: zakatEligible ? isZakat : false, emailOptIn: emailOptIn && hasEmail, whatsappOptIn: whatsappOptIn && hasPhone, consentMeta, }) } catch { setSubmitting(false) } } return (

Almost there!

We just need your details to process this pledge

{/* ── Contact Details ── */}
{/* Name */}
setName(e.target.value)} autoComplete="name" className="w-full h-14 px-4 rounded-2xl border-2 border-gray-200 bg-white text-base font-medium placeholder:text-gray-300 focus:border-trust-blue focus:ring-4 focus:ring-trust-blue/10 outline-none transition-all" /> {name && (
)}
{/* Email */}
setEmail(e.target.value)} autoComplete="email" inputMode="email" className="w-full h-14 pl-12 pr-4 rounded-2xl border-2 border-gray-200 bg-white text-base font-medium placeholder:text-gray-300 focus:border-trust-blue focus:ring-4 focus:ring-trust-blue/10 outline-none transition-all" /> {hasEmail && (
)}
{/* Phone */}
setPhone(e.target.value)} autoComplete="tel" inputMode="tel" className="w-full h-14 pl-12 pr-4 rounded-2xl border-2 border-gray-200 bg-white text-base font-medium placeholder:text-gray-300 focus:border-trust-blue focus:ring-4 focus:ring-trust-blue/10 outline-none transition-all" /> {hasPhone && (
)}
{!hasEmail && !hasPhone && (

Enter at least an email or mobile number

)}
{/* ── Zakat ── */} {zakatEligible && ( )} {/* ── Gift Aid (HMRC) ── */}
{/* Gift Aid address + declaration (shown when Gift Aid is on) */} {giftAid && showGiftAidAddress && (
{/* HMRC requires home address */}
Home address (required by HMRC for Gift Aid)
setAddressLine1(e.target.value)} autoComplete="address-line1" className="w-full h-12 px-4 rounded-xl border-2 border-gray-200 bg-white text-sm font-medium placeholder:text-gray-300 focus:border-success-green focus:ring-4 focus:ring-success-green/10 outline-none transition-all" /> {addressLine1 && (
)}
setPostcode(e.target.value.toUpperCase())} autoComplete="postal-code" className="w-full h-12 px-4 rounded-xl border-2 border-gray-200 bg-white text-sm font-medium placeholder:text-gray-300 focus:border-success-green focus:ring-4 focus:ring-success-green/10 outline-none transition-all uppercase" /> {postcode.length >= 5 && (
)}
{/* HMRC declaration — exact model wording */}

Gift Aid Declaration

{GIFT_AID_DECLARATION}

{name && (

By ticking Gift Aid above, {name} declares this donation{orgName ? ` to ${orgName}` : ""} is eligible for Gift Aid.

)}
{(!addressLine1 || postcode.length < 5) && (

Please complete your address to claim Gift Aid

)}
)}
{/* ── Communication Consent (GDPR / PECR) ── */}

Communication preferences

{/* Email consent — only shown if email is provided */} {hasEmail && ( )} {/* WhatsApp consent — only shown if phone is provided */} {hasPhone && ( )} {!hasEmail && !hasPhone && (

Enter an email or mobile number above to set your communication preferences.

)}
{/* ── Submit ── */}
Your data is encrypted and only shared with the charity you're pledging to
) } /* ── Reusable consent checkbox ── */ function ConsentCheckbox({ checked, onChange, icon, label, description }: { checked: boolean onChange: (v: boolean) => void icon: string label: string description: string }) { return ( ) }