feat: add AFC Store with MercadoPago purchases and prize redemption
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
Players can now buy AfterCoin with real money (MercadoPago Checkout Pro, $15 MXN/AFC) and redeem AFC for gift cards or cash withdrawals. Admin fulfills redemptions manually. - Bridge: payments + redemptions tables, CRUD routes, PATCH auth - Next.js API: verify-disk, balance, create-preference, webhook (idempotent minting with HMAC signature verification), redeem, payment/redemption history - Frontend: hub, buy flow (4 packages + custom), redeem flow (gift cards + cash out), success/failure/pending pages, history with tabs, 8 components - i18n: full English + Spanish translations - Infra: nginx /api/afc/ → Next.js, docker-compose env vars, .env.example Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
apps/web/src/components/afc/AfcPackageCard.tsx
Normal file
49
apps/web/src/components/afc/AfcPackageCard.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
"use client";
|
||||
|
||||
interface AfcPackageCardProps {
|
||||
amount: number;
|
||||
priceMxn: number;
|
||||
popular?: boolean;
|
||||
loading?: boolean;
|
||||
onSelect: () => void;
|
||||
}
|
||||
|
||||
export function AfcPackageCard({
|
||||
amount,
|
||||
priceMxn,
|
||||
popular,
|
||||
loading,
|
||||
onSelect,
|
||||
}: AfcPackageCardProps) {
|
||||
return (
|
||||
<button
|
||||
onClick={onSelect}
|
||||
disabled={loading}
|
||||
className={`relative group block w-full text-left bg-gray-900 rounded-2xl p-6 border transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] disabled:opacity-50 ${
|
||||
popular
|
||||
? "border-amber-500/50 shadow-lg shadow-amber-500/10"
|
||||
: "border-white/5 hover:border-amber-500/30"
|
||||
}`}
|
||||
>
|
||||
{popular && (
|
||||
<span className="absolute -top-3 left-1/2 -translate-x-1/2 bg-amber-500 text-black text-xs font-bold px-3 py-1 rounded-full">
|
||||
POPULAR
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-14 h-14 rounded-full bg-amber-500/10 border border-amber-500/30 flex items-center justify-center shrink-0 group-hover:bg-amber-500/20 transition-colors">
|
||||
<span className="text-xl font-bold text-amber-400">{amount}</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="text-white font-semibold text-lg">{amount} AFC</p>
|
||||
<p className="text-gray-500 text-sm">AfterCoin</p>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<p className="text-2xl font-bold text-white">${priceMxn}</p>
|
||||
<p className="text-xs text-gray-500">MXN</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user