85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
'use client';
|
|
import React, { useState } from 'react';
|
|
import { Heart, CheckCircle } from 'lucide-react';
|
|
import type { Campaign } from '@/lib/api';
|
|
|
|
const AMOUNTS = [10, 25, 50, 100, 250];
|
|
|
|
export default function DonationCard({ campaign }: { campaign: Campaign }) {
|
|
const [selected, setSelected] = useState(25);
|
|
const [custom, setCustom] = useState('');
|
|
const [donated, setDonated] = useState(false);
|
|
const pct = Math.min(100, Math.round((campaign.raised / campaign.goal) * 100));
|
|
|
|
const handleDonate = () => {
|
|
// Stripe would go here
|
|
setDonated(true);
|
|
setTimeout(() => setDonated(false), 3000);
|
|
};
|
|
|
|
return (
|
|
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-7 hover:border-gold/20 transition-all space-y-6">
|
|
<div>
|
|
<h3 className="font-bold text-white text-xl">{campaign.title}</h3>
|
|
<p className="text-sm text-stone-400 leading-relaxed mt-2">{campaign.description}</p>
|
|
</div>
|
|
|
|
{/* Progress */}
|
|
<div className="space-y-2">
|
|
<div className="flex justify-between text-xs font-semibold">
|
|
<span className="text-gold">${campaign.raised.toLocaleString()} raised</span>
|
|
<span className="text-stone-500">Goal: ${campaign.goal.toLocaleString()}</span>
|
|
</div>
|
|
<div className="h-2 bg-black/40 rounded-full overflow-hidden">
|
|
<div
|
|
className="h-full bg-gradient-to-r from-teal to-gold rounded-full transition-all duration-1000"
|
|
style={{ width: `${pct}%` }}
|
|
/>
|
|
</div>
|
|
<p className="text-xs text-stone-500 font-medium text-right">{pct}% complete</p>
|
|
</div>
|
|
|
|
{/* Amount selector */}
|
|
<div className="space-y-3">
|
|
<div className="grid grid-cols-5 gap-2">
|
|
{AMOUNTS.map((amt) => (
|
|
<button
|
|
key={amt}
|
|
onClick={() => { setSelected(amt); setCustom(''); }}
|
|
className={`py-2 rounded-lg text-sm font-bold transition-all ${
|
|
selected === amt && !custom
|
|
? 'bg-gold text-deepGreen shadow-lg shadow-gold/20'
|
|
: 'bg-black/40 text-stone-300 hover:bg-white/10'
|
|
}`}
|
|
>
|
|
${amt}
|
|
</button>
|
|
))}
|
|
</div>
|
|
<input
|
|
type="number"
|
|
value={custom}
|
|
onChange={(e) => { setCustom(e.target.value); setSelected(0); }}
|
|
placeholder="Custom amount"
|
|
className="w-full bg-black/40 border border-white/10 rounded-lg px-4 py-2.5 text-sm text-white placeholder:text-stone-600 focus:outline-none focus:border-teal/50"
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
onClick={handleDonate}
|
|
className={`w-full py-3.5 rounded-xl font-bold text-sm flex items-center justify-center gap-2 transition-all ${
|
|
donated
|
|
? 'bg-emerald-600 text-white'
|
|
: 'bg-gold text-deepGreen hover:bg-goldLight shadow-lg shadow-gold/20 active:scale-95'
|
|
}`}
|
|
>
|
|
{donated ? (
|
|
<><CheckCircle size={18} /> Thank you!</>
|
|
) : (
|
|
<><Heart size={16} /> Donate ${custom || selected}</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|