169 lines
No EOL
6.3 KiB
JavaScript
169 lines
No EOL
6.3 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { Helmet } from 'react-helmet';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { ArrowLeft, Check, Wallet, ShieldCheck, CreditCard } from 'lucide-react';
|
|
import { toast } from '@/components/ui/use-toast';
|
|
import { motion } from 'framer-motion';
|
|
import { useSignature } from '@/contexts/SignatureContext';
|
|
|
|
const CreditPackage = ({ credits, price, savings, popular, onSelect, loading }) => (
|
|
<motion.div
|
|
whileHover={{ scale: 1.02 }}
|
|
className={`relative p-6 rounded-2xl border-2 cursor-pointer transition-all ${
|
|
popular
|
|
? 'border-[#338660] bg-white dark:bg-gray-900 shadow-xl shadow-[#338660]/10'
|
|
: 'border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-950 hover:border-[#338660]/50'
|
|
}`}
|
|
onClick={onSelect}
|
|
>
|
|
{popular && (
|
|
<div className="absolute -top-3 left-1/2 -translate-x-1/2 bg-[#338660] text-white px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider">
|
|
Recommandé
|
|
</div>
|
|
)}
|
|
|
|
<div className="text-center mb-6">
|
|
<div className="text-4xl font-extrabold text-gray-900 dark:text-white mb-2">{credits}</div>
|
|
<div className="text-sm font-medium text-gray-500 uppercase tracking-wide">Crédits</div>
|
|
</div>
|
|
|
|
<div className="text-center mb-6">
|
|
<div className="text-3xl font-bold text-[#338660]">{price}€</div>
|
|
<div className="text-xs text-gray-400">HT</div>
|
|
<div className="text-xs text-gray-500 mt-1">{(price / credits).toFixed(2)}€ / signature</div>
|
|
</div>
|
|
|
|
{savings && (
|
|
<div className="mb-6 flex justify-center">
|
|
<span className="bg-green-100 text-green-800 text-xs font-bold px-2 py-1 rounded-lg">
|
|
Économisez {savings}%
|
|
</span>
|
|
</div>
|
|
)}
|
|
|
|
<ul className="space-y-3 mb-6">
|
|
<li className="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<Check className="w-4 h-4 text-[#338660] mr-2" />
|
|
Signature certifiée eIDAS
|
|
</li>
|
|
<li className="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<Check className="w-4 h-4 text-[#338660] mr-2" />
|
|
Horodatage qualifié
|
|
</li>
|
|
<li className="flex items-center text-sm text-gray-600 dark:text-gray-400">
|
|
<Check className="w-4 h-4 text-[#338660] mr-2" />
|
|
Archivage 10 ans
|
|
</li>
|
|
</ul>
|
|
|
|
<button
|
|
disabled={loading}
|
|
className={`w-full py-3 rounded-xl font-bold transition-all ${
|
|
popular
|
|
? 'bg-[#338660] text-white hover:bg-[#2A6F4F] shadow-lg shadow-[#338660]/20'
|
|
: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700'
|
|
}`}
|
|
>
|
|
{loading ? 'Traitement...' : 'Acheter'}
|
|
</button>
|
|
</motion.div>
|
|
);
|
|
|
|
const SignatureCreditPurchase = () => {
|
|
const navigate = useNavigate();
|
|
const { stats, purchaseCredits } = useSignature();
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const handlePurchase = async (amount, price) => {
|
|
setLoading(true);
|
|
// Simulate payment processing
|
|
setTimeout(async () => {
|
|
const success = await purchaseCredits(amount);
|
|
setLoading(false);
|
|
if (success) {
|
|
toast({
|
|
title: "Achat confirmé",
|
|
description: `${amount} crédits ont été ajoutés à votre solde.`,
|
|
variant: "success"
|
|
});
|
|
navigate('/home/signature/dashboard');
|
|
}
|
|
}, 1500);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Helmet>
|
|
<title>Achat de crédits - Signature - Bijou ERP</title>
|
|
</Helmet>
|
|
|
|
<div className="max-w-5xl mx-auto space-y-8">
|
|
<div className="flex items-center gap-4">
|
|
<button onClick={() => navigate('/home/signature/dashboard')} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg">
|
|
<ArrowLeft className="w-5 h-5" />
|
|
</button>
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Recharger mon compte</h1>
|
|
<p className="text-gray-500">Choisissez le pack adapté à vos besoins</p>
|
|
</div>
|
|
<div className="ml-auto flex items-center gap-2 bg-white dark:bg-gray-950 px-4 py-2 rounded-xl border border-gray-200 dark:border-gray-800">
|
|
<Wallet className="w-5 h-5 text-[#338660]" />
|
|
<span className="font-medium">Solde actuel : </span>
|
|
<span className="font-bold text-[#338660]">{stats?.credits.remaining || 0} crédits</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
<CreditPackage
|
|
credits={10}
|
|
price={15}
|
|
onSelect={() => handlePurchase(10, 15)}
|
|
loading={loading}
|
|
/>
|
|
<CreditPackage
|
|
credits={25}
|
|
price={35}
|
|
savings={7}
|
|
onSelect={() => handlePurchase(25, 35)}
|
|
loading={loading}
|
|
/>
|
|
<CreditPackage
|
|
credits={50}
|
|
price={65}
|
|
savings={13}
|
|
popular
|
|
onSelect={() => handlePurchase(50, 65)}
|
|
loading={loading}
|
|
/>
|
|
<CreditPackage
|
|
credits={100}
|
|
price={120}
|
|
savings={20}
|
|
onSelect={() => handlePurchase(100, 120)}
|
|
loading={loading}
|
|
/>
|
|
</div>
|
|
|
|
<div className="bg-gray-50 dark:bg-gray-900/50 rounded-2xl p-8 flex flex-col md:flex-row items-center justify-between gap-8">
|
|
<div className="flex items-center gap-4">
|
|
<div className="p-3 bg-white dark:bg-gray-800 rounded-xl shadow-sm">
|
|
<ShieldCheck className="w-8 h-8 text-[#338660]" />
|
|
</div>
|
|
<div>
|
|
<h3 className="font-bold text-lg">Paiement 100% sécurisé</h3>
|
|
<p className="text-gray-500">Transactions chiffrées via Stripe. Facture disponible immédiatement.</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-4 opacity-50 grayscale hover:grayscale-0 transition-all">
|
|
{/* Simple representation of payment methods */}
|
|
<div className="h-8 w-12 bg-gray-300 rounded"></div>
|
|
<div className="h-8 w-12 bg-gray-300 rounded"></div>
|
|
<div className="h-8 w-12 bg-gray-300 rounded"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default SignatureCreditPurchase; |