Add Payment Gateway selection to Settings page

This commit is contained in:
CycroftX
2026-02-03 21:04:57 +05:30
parent 456c2d7d57
commit 10e8e28c52
2 changed files with 138 additions and 31 deletions

View File

@@ -0,0 +1,132 @@
import { CreditCard, CheckCircle2, RotateCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { useState } from "react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
const availableGateways = [
{
id: "stripe",
name: "Stripe",
logo: "https://upload.wikimedia.org/wikipedia/commons/b/ba/Stripe_Logo%2C_revised_2016.svg",
fee: "2.9% + ₹30",
status: "Connected",
},
{
id: "razorpay",
name: "Razorpay",
logo: "https://upload.wikimedia.org/wikipedia/commons/8/89/Razorpay_logo.svg",
fee: "2%",
status: "Available",
},
{
id: "phonepe",
name: "PhonePe",
logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/7/71/PhonePe_Logo.svg/2560px-PhonePe_Logo.svg.png",
fee: "1.9%",
status: "Available",
},
{
id: "cashfree",
name: "Cashfree",
logo: "https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Cashfree_Payments_Logo.svg/2560px-Cashfree_Payments_Logo.svg.png",
fee: "1.95%",
status: "Available",
}
];
export function PaymentGatewayCard() {
const [activeGateway, setActiveGateway] = useState("stripe");
const [loading, setLoading] = useState<string | null>(null);
const handleGatewayChange = (id: string) => {
if (activeGateway === id) return;
setLoading(id);
// Simulate connection lag
setTimeout(() => {
setActiveGateway(id);
setLoading(null);
toast.success(`Switched active payment gateway to ${availableGateways.find(g => g.id === id)?.name}`);
}, 1500);
};
return (
<div className="neu-card p-6 h-full flex flex-col">
<div className="flex items-center gap-4 mb-6">
<div className="h-12 w-12 rounded-xl bg-indigo-500/10 flex items-center justify-center">
<CreditCard className="h-6 w-6 text-indigo-600 dark:text-indigo-400" />
</div>
<div>
<h3 className="font-bold text-lg text-foreground">Payment Gateway</h3>
<p className="text-sm text-muted-foreground">Collection preferences</p>
</div>
<div className="ml-auto">
{loading ? (
<RotateCw className="h-4 w-4 text-indigo-500 animate-spin" />
) : (
<Badge className="bg-indigo-500/15 text-indigo-600 hover:bg-indigo-500/25 border-none gap-1">
<div className="h-1.5 w-1.5 rounded-full bg-indigo-500 animate-pulse" />
Processing
</Badge>
)}
</div>
</div>
<div className="flex-1 space-y-4">
<RadioGroup value={activeGateway} onValueChange={handleGatewayChange} className="space-y-3">
{availableGateways.map((gateway) => (
<div
key={gateway.id}
className={cn(
"relative flex items-center justify-between p-4 rounded-xl border transition-all cursor-pointer",
activeGateway === gateway.id
? "border-indigo-500/50 bg-indigo-500/5 shadow-neu-sm"
: "border-border/50 bg-card hover:bg-secondary/50"
)}
onClick={() => handleGatewayChange(gateway.id)}
>
<div className="flex items-center gap-4">
<RadioGroupItem value={gateway.id} id={gateway.id} className="border-indigo-500 text-indigo-500" />
<div className="h-8 w-20 flex items-center justify-center bg-white rounded p-1">
{/* Placeholder for logos if external works, else text */}
{/* Using text fallback for safety/offline dev */}
<span className="font-bold text-xs text-black">{gateway.name}</span>
</div>
<div>
<Label htmlFor={gateway.id} className="font-semibold cursor-pointer">{gateway.name}</Label>
<p className="text-xs text-muted-foreground">Fee: {gateway.fee}</p>
</div>
</div>
{gateway.status === "Connected" || activeGateway === gateway.id ? (
<CheckCircle2 className="h-5 w-5 text-indigo-500" />
) : (
<Button
variant="ghost"
size="sm"
className="text-xs text-muted-foreground h-7"
onClick={(e) => {
e.stopPropagation();
handleGatewayChange(gateway.id);
}}
>
Connect
</Button>
)}
</div>
))}
</RadioGroup>
</div>
<div className="mt-6 pt-6 border-t border-border/50">
<p className="text-xs text-muted-foreground text-center">
Processing payments settled in <b>T+2 days</b> via selected gateway.
</p>
</div>
</div>
);
}