feat: premium UI overhaul, AI suggestions, WAHA WhatsApp integration
PREMIUM UI: - All animations: fade-up, scale-in, stagger children, confetti celebration - Glass effects, gradient icons, premium card hover states - Custom CSS: shimmer, pulse-ring, bounce, counter-roll animations - Smooth progress bar with gradient AI-POWERED (GPT-4o-mini nano model): - Smart amount suggestions based on peer data (/api/ai/suggest) - Social proof: '42 people pledged · Average £85' - AI-generated nudge text for conversion - AI fuzzy matching for bank reconciliation - AI reminder message generation WAHA WHATSAPP INTEGRATION: - Auto-send pledge receipt with bank details via WhatsApp - 4-step reminder sequence: gentle → nudge → urgent → final - Chatbot: donors reply PAID, HELP, CANCEL, STATUS - Volunteer notification on new pledges - WhatsApp status in dashboard settings - Webhook endpoint for incoming messages DONOR FLOW (CRO): - Amount step: AI suggestions, Gift Aid preview, social proof, haptic feedback - Payment step: trust signals, fee comparison, benefit badges - Identity step: email/phone toggle, WhatsApp reminder indicator - Bank instructions: tap-to-copy each field, WhatsApp delivery confirmation - Confirmation: confetti, pulse animation, share CTA, WhatsApp receipt COMPOSE: - Added WAHA env vars + qc-comms network for WhatsApp access
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { Building2, CreditCard, Landmark } from "lucide-react"
|
||||
import { Building2, CreditCard, Landmark, Shield, CheckCircle2 } from "lucide-react"
|
||||
|
||||
interface Props {
|
||||
onSelect: (rail: "bank" | "gocardless" | "card") => void
|
||||
@@ -8,90 +8,115 @@ interface Props {
|
||||
}
|
||||
|
||||
export function PaymentStep({ onSelect, amount }: Props) {
|
||||
const pounds = (amount / 100).toFixed(2)
|
||||
const pounds = (amount / 100).toFixed(0)
|
||||
const giftAidTotal = ((amount + amount * 0.25) / 100).toFixed(0)
|
||||
|
||||
const options = [
|
||||
{
|
||||
id: "bank" as const,
|
||||
icon: Building2,
|
||||
title: "Bank Transfer",
|
||||
subtitle: "Zero fees — 100% goes to charity",
|
||||
subtitle: "100% goes to charity — zero fees",
|
||||
tag: "Recommended",
|
||||
tagColor: "bg-success-green text-white",
|
||||
detail: "Use your banking app to transfer directly. We'll give you the details.",
|
||||
fee: "No fees",
|
||||
feeColor: "text-success-green",
|
||||
tagClass: "bg-success-green text-white",
|
||||
detail: "We'll give you the bank details. Transfer in your own time.",
|
||||
fee: "Free",
|
||||
feeClass: "text-success-green font-bold",
|
||||
iconBg: "from-emerald-500 to-green-600",
|
||||
highlight: true,
|
||||
benefits: ["Zero fees", "Most charities prefer this"],
|
||||
},
|
||||
{
|
||||
id: "gocardless" as const,
|
||||
icon: Landmark,
|
||||
title: "Direct Debit",
|
||||
subtitle: "Automatic collection — set and forget",
|
||||
tag: "Set up once",
|
||||
tagColor: "bg-trust-blue/10 text-trust-blue",
|
||||
detail: "We'll collect via GoCardless. Protected by the Direct Debit Guarantee.",
|
||||
tag: "Hassle-free",
|
||||
tagClass: "bg-trust-blue/10 text-trust-blue",
|
||||
detail: "GoCardless collects it for you. Protected by the DD Guarantee.",
|
||||
fee: "1% + 20p",
|
||||
feeColor: "text-muted-foreground",
|
||||
feeClass: "text-muted-foreground",
|
||||
iconBg: "from-trust-blue to-blue-600",
|
||||
highlight: false,
|
||||
benefits: ["No action needed", "DD Guarantee"],
|
||||
},
|
||||
{
|
||||
id: "card" as const,
|
||||
icon: CreditCard,
|
||||
title: "Debit or Credit Card",
|
||||
subtitle: "Pay instantly by Visa, Mastercard, or Amex",
|
||||
title: "Card Payment",
|
||||
subtitle: "Visa, Mastercard, Amex — instant",
|
||||
tag: "Instant",
|
||||
tagColor: "bg-purple-100 text-purple-700",
|
||||
detail: "Secure payment powered by Stripe. Receipt emailed immediately.",
|
||||
tagClass: "bg-purple-100 text-purple-700",
|
||||
detail: "Powered by Stripe. Receipt emailed instantly.",
|
||||
fee: "1.4% + 20p",
|
||||
feeColor: "text-muted-foreground",
|
||||
feeClass: "text-muted-foreground",
|
||||
iconBg: "from-purple-500 to-violet-600",
|
||||
highlight: false,
|
||||
benefits: ["Instant confirmation", "All major cards"],
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="max-w-md mx-auto pt-4 space-y-6">
|
||||
<div className="max-w-md mx-auto pt-2 space-y-6 animate-fade-up">
|
||||
<div className="text-center space-y-2">
|
||||
<h1 className="text-2xl font-extrabold text-gray-900">
|
||||
<h1 className="text-2xl font-black text-gray-900 tracking-tight">
|
||||
How would you like to pay?
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
<p className="text-base text-muted-foreground">
|
||||
Your pledge: <span className="font-bold text-foreground">£{pounds}</span>
|
||||
<span className="text-success-green text-xs ml-1">(£{giftAidTotal} with Gift Aid)</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-3 stagger-children">
|
||||
{options.map((opt) => (
|
||||
<button
|
||||
key={opt.id}
|
||||
onClick={() => onSelect(opt.id)}
|
||||
className="w-full text-left tap-target rounded-2xl border-2 border-gray-200 bg-white p-5 hover:border-trust-blue/50 active:scale-[0.99] transition-all group"
|
||||
className={`
|
||||
w-full text-left rounded-2xl border-2 bg-white p-5 transition-all duration-200 group card-hover
|
||||
${opt.highlight
|
||||
? "border-success-green/40 shadow-sm shadow-success-green/10 hover:border-success-green hover:shadow-lg hover:shadow-success-green/15"
|
||||
: "border-gray-200 hover:border-trust-blue/40 hover:shadow-lg hover:shadow-trust-blue/10"
|
||||
}
|
||||
`}
|
||||
>
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="rounded-xl bg-trust-blue/5 p-3 group-hover:bg-trust-blue/10 transition-colors">
|
||||
<opt.icon className="h-6 w-6 text-trust-blue" />
|
||||
<div className={`rounded-xl bg-gradient-to-br ${opt.iconBg} p-3 shadow-lg shadow-trust-blue/10 group-hover:scale-105 transition-transform`}>
|
||||
<opt.icon className="h-5 w-5 text-white" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="font-bold text-gray-900">{opt.title}</span>
|
||||
<span className={`text-xs font-semibold px-2 py-0.5 rounded-full ${opt.tagColor}`}>
|
||||
<span className={`text-[10px] font-bold px-2 py-0.5 rounded-full ${opt.tagClass}`}>
|
||||
{opt.tag}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mt-0.5">{opt.subtitle}</p>
|
||||
<p className="text-xs text-muted-foreground/70 mt-1">{opt.detail}</p>
|
||||
<p className={`text-xs font-medium mt-1 ${opt.feeColor}`}>
|
||||
Fee: {opt.fee}
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-muted-foreground/40 group-hover:text-trust-blue transition-colors text-xl">
|
||||
→
|
||||
<div className="flex items-center gap-3 mt-2">
|
||||
{opt.benefits.map((b, i) => (
|
||||
<span key={i} className="text-[11px] text-muted-foreground inline-flex items-center gap-1">
|
||||
<CheckCircle2 className="h-3 w-3 text-success-green" />
|
||||
{b}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-2 pt-2 border-t border-gray-100">
|
||||
<span className={`text-xs ${opt.feeClass}`}>Fee: {opt.fee}</span>
|
||||
<span className="text-xs text-trust-blue font-medium opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
Select →
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-center text-xs text-muted-foreground">
|
||||
All payments are secure. Bank transfers mean 100% reaches the charity.
|
||||
</p>
|
||||
<div className="flex items-center justify-center gap-2 text-xs text-muted-foreground animate-fade-in" style={{ animationDelay: "300ms" }}>
|
||||
<Shield className="h-3.5 w-3.5" />
|
||||
<span>All payments are encrypted and secure</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user