221 lines
5.5 KiB
TypeScript
221 lines
5.5 KiB
TypeScript
import React from 'react';
|
|
|
|
export type PaymentMethodItem = {
|
|
name: string;
|
|
icon_url?: string;
|
|
};
|
|
|
|
export const DEFAULT_PAYMENT_METHODS: PaymentMethodItem[] = [
|
|
{ name: 'Visa' },
|
|
{ name: 'Mastercard' },
|
|
{ name: 'RuPay' },
|
|
{ name: 'UPI' },
|
|
{ name: 'Razorpay' },
|
|
];
|
|
|
|
function methodKey(name?: string): string {
|
|
return String(name || '')
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, '');
|
|
}
|
|
|
|
const shell =
|
|
'h-8 min-w-[52px] px-2 rounded border border-gray-200 bg-white flex items-center justify-center shadow-[0_1px_2px_rgba(15,23,42,0.04)] select-none';
|
|
|
|
function VisaMark() {
|
|
return (
|
|
<div className={shell} title="Visa">
|
|
<svg width="38" height="14" viewBox="0 0 48 16" aria-hidden>
|
|
<text
|
|
x="0"
|
|
y="13"
|
|
fontSize="13"
|
|
fontWeight="800"
|
|
fontStyle="italic"
|
|
fontFamily="Arial, Helvetica, sans-serif"
|
|
fill="#1A1F71"
|
|
>
|
|
VISA
|
|
</text>
|
|
</svg>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function MastercardMark() {
|
|
return (
|
|
<div className={`${shell} gap-1.5`} title="Mastercard">
|
|
<span className="relative w-[22px] h-[14px]" aria-hidden>
|
|
<span className="absolute left-0 top-0.5 w-[14px] h-[14px] rounded-full bg-[#EB001B]" />
|
|
<span className="absolute right-0 top-0.5 w-[14px] h-[14px] rounded-full bg-[#F79E1B]" />
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function RuPayMark() {
|
|
return (
|
|
<div className={shell} title="RuPay">
|
|
<svg width="44" height="14" viewBox="0 0 54 16" aria-hidden>
|
|
<text
|
|
x="0"
|
|
y="12.5"
|
|
fontSize="12"
|
|
fontWeight="800"
|
|
fontFamily="Arial, Helvetica, sans-serif"
|
|
fill="#0B5CAB"
|
|
>
|
|
RuPay
|
|
</text>
|
|
</svg>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function UpiMark() {
|
|
return (
|
|
<div className={shell} title="UPI">
|
|
<svg width="36" height="16" viewBox="0 0 36 16" aria-hidden>
|
|
<text
|
|
x="1"
|
|
y="12.5"
|
|
fontSize="12"
|
|
fontWeight="800"
|
|
fontFamily="Arial, Helvetica, sans-serif"
|
|
fill="#097939"
|
|
>
|
|
UPI
|
|
</text>
|
|
</svg>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function AmexMark() {
|
|
return (
|
|
<div className={`${shell} bg-[#0070CD] border-[#0070CD]`} title="American Express">
|
|
<span className="text-[9px] font-extrabold tracking-wide text-white uppercase">
|
|
AMEX
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function RazorpayMark() {
|
|
return (
|
|
<div className={shell} title="Razorpay">
|
|
<span className="text-[10px] font-extrabold text-[#072654] tracking-tight">
|
|
razor<span className="text-[#3395FF]">pay</span>
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PaypalMark() {
|
|
return (
|
|
<div className={shell} title="PayPal">
|
|
<span className="text-[11px] font-black italic text-[#003087]">PayPal</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function GpayMark() {
|
|
return (
|
|
<div className={shell} title="Google Pay">
|
|
<span className="text-[10px] font-bold text-gray-700">GPay</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PhonePeMark() {
|
|
return (
|
|
<div className={shell} title="PhonePe">
|
|
<span className="text-[10px] font-extrabold text-[#5F259F]">PhonePe</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PaytmMark() {
|
|
return (
|
|
<div className={shell} title="Paytm">
|
|
<span className="text-[10px] font-extrabold text-[#00BAF2]">Paytm</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function NetBankingMark() {
|
|
return (
|
|
<div className={shell} title="Net banking">
|
|
<span className="text-[9px] font-bold text-gray-700">NetBank</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function WalletMark() {
|
|
return (
|
|
<div className={shell} title="Wallets">
|
|
<span className="text-[9px] font-bold text-gray-700">Wallet</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function TextMark({ name }: { name: string }) {
|
|
return (
|
|
<div className={shell} title={name}>
|
|
<span className="text-[10px] font-bold text-gray-700 max-w-[72px] truncate">
|
|
{name}
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function PaymentMethodBadge({ name }: { name: string }) {
|
|
const key = methodKey(name);
|
|
if (key.includes('visa')) return <VisaMark />;
|
|
if (key.includes('master') || key.includes('maestro')) return <MastercardMark />;
|
|
if (key.includes('rupay')) return <RuPayMark />;
|
|
if (key === 'upi' || key.includes('bhim')) return <UpiMark />;
|
|
if (key.includes('amex') || key.includes('americanexpress')) return <AmexMark />;
|
|
if (key.includes('razor')) return <RazorpayMark />;
|
|
if (key.includes('paypal')) return <PaypalMark />;
|
|
if (key.includes('gpay') || key.includes('googlepay')) return <GpayMark />;
|
|
if (key.includes('phonepe')) return <PhonePeMark />;
|
|
if (key.includes('paytm')) return <PaytmMark />;
|
|
if (key.includes('netbank') || key.includes('netbanking')) return <NetBankingMark />;
|
|
if (key.includes('wallet')) return <WalletMark />;
|
|
return <TextMark name={name} />;
|
|
}
|
|
|
|
export function PaymentMethodBadges({
|
|
methods,
|
|
className = '',
|
|
}: {
|
|
methods?: PaymentMethodItem[] | null;
|
|
className?: string;
|
|
}) {
|
|
const seen = new Set<string>();
|
|
const list: PaymentMethodItem[] = [];
|
|
const source =
|
|
methods && methods.length > 0 ? methods : DEFAULT_PAYMENT_METHODS;
|
|
|
|
for (const item of source) {
|
|
const name = String(item?.name || '').trim();
|
|
if (!name) continue;
|
|
const key = methodKey(name);
|
|
if (seen.has(key)) continue;
|
|
seen.add(key);
|
|
list.push({ name });
|
|
}
|
|
|
|
if (list.length === 0) {
|
|
DEFAULT_PAYMENT_METHODS.forEach((item) => list.push(item));
|
|
}
|
|
|
|
return (
|
|
<div className={`flex items-center gap-2 flex-wrap ${className}`}>
|
|
{list.map((pm) => (
|
|
<PaymentMethodBadge key={methodKey(pm.name)} name={pm.name} />
|
|
))}
|
|
</div>
|
|
);
|
|
}
|