70 lines
2.6 KiB
TypeScript
70 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from 'react';
|
|
import { updateBusinessPlan } from '@/app/actions/plans';
|
|
import { toast } from 'react-hot-toast';
|
|
import { CreditCard, Loader2 } from 'lucide-react';
|
|
|
|
interface PlanSelectorProps {
|
|
businessId: string;
|
|
currentPlan: string;
|
|
}
|
|
|
|
const PLANS = [
|
|
{ id: 'STARTER', name: 'Starter', color: 'text-slate-400', bg: 'bg-slate-400/10' },
|
|
{ id: 'BOOSTER', name: 'Booster', color: 'text-brand-400', bg: 'bg-brand-400/10' },
|
|
{ id: 'EMPIRE', name: 'Empire', color: 'text-amber-400', bg: 'bg-amber-400/10' }
|
|
];
|
|
|
|
export default function PlanSelector({ businessId, currentPlan }: PlanSelectorProps) {
|
|
const [isUpdating, setIsUpdating] = useState(false);
|
|
const [plan, setPlan] = useState(currentPlan);
|
|
|
|
const handlePlanChange = async (newPlan: string) => {
|
|
setIsUpdating(true);
|
|
try {
|
|
const result = await updateBusinessPlan(businessId, newPlan as any);
|
|
if (result.success) {
|
|
setPlan(newPlan);
|
|
toast.success(`Forfait mis à jour vers ${newPlan}`);
|
|
} else {
|
|
toast.error(result.error || "Erreur lors du changement de forfait");
|
|
// Reset to old plan in UI
|
|
setPlan(currentPlan);
|
|
}
|
|
} catch (error) {
|
|
toast.error("Erreur réseau");
|
|
setPlan(currentPlan);
|
|
} finally {
|
|
setIsUpdating(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="relative inline-flex items-center group">
|
|
<div className={`absolute left-2 text-slate-500 pointer-events-none ${isUpdating ? 'animate-spin' : ''}`}>
|
|
{isUpdating ? <Loader2 className="w-3.5 h-3.5" /> : <CreditCard className="w-3.5 h-3.5" />}
|
|
</div>
|
|
<select
|
|
value={plan}
|
|
onChange={(e) => handlePlanChange(e.target.value)}
|
|
disabled={isUpdating}
|
|
className={`appearance-none bg-slate-900 border border-slate-700 pl-8 pr-8 py-1.5 rounded-lg text-xs font-bold uppercase tracking-wider focus:outline-none focus:ring-2 focus:ring-brand-500/50 transition-all cursor-pointer hover:border-slate-600 disabled:opacity-50 disabled:cursor-not-allowed ${
|
|
PLANS.find(p => p.id === plan)?.color || 'text-white'
|
|
}`}
|
|
>
|
|
{PLANS.map((p) => (
|
|
<option key={p.id} value={p.id} className="bg-slate-900 text-white font-sans capitalize">
|
|
{p.name}
|
|
</option>
|
|
))}
|
|
</select>
|
|
<div className="absolute right-2 pointer-events-none">
|
|
<svg className="w-3 h-3 text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|