69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
import Link from 'next/link';
|
|
import { Lock } from 'lucide-react';
|
|
import { useSubscription } from '@/lib/context/subscription-context';
|
|
import type { PlanFeature } from '@/lib/api/subscriptions';
|
|
|
|
interface FeatureGateProps {
|
|
feature: PlanFeature;
|
|
children: React.ReactNode;
|
|
fallback?: React.ReactNode;
|
|
}
|
|
|
|
const FEATURE_MIN_PLAN: Record<PlanFeature, string> = {
|
|
dashboard: 'Silver',
|
|
wiki: 'Silver',
|
|
user_management: 'Silver',
|
|
csv_export: 'Silver',
|
|
api_access: 'Gold',
|
|
custom_interface: 'Platinium',
|
|
dedicated_kam: 'Platinium',
|
|
};
|
|
|
|
export default function FeatureGate({ feature, children, fallback }: FeatureGateProps) {
|
|
const { hasFeature, loading } = useSubscription();
|
|
|
|
if (loading) {
|
|
return <>{children}</>;
|
|
}
|
|
|
|
if (hasFeature(feature)) {
|
|
return <>{children}</>;
|
|
}
|
|
|
|
if (fallback) {
|
|
return <>{fallback}</>;
|
|
}
|
|
|
|
const minPlan = FEATURE_MIN_PLAN[feature] || 'Silver';
|
|
|
|
return (
|
|
<div className="relative">
|
|
<div className="opacity-30 pointer-events-none select-none blur-sm">
|
|
{children}
|
|
</div>
|
|
<div className="absolute inset-0 flex items-center justify-center bg-white/60 backdrop-blur-[2px] rounded-lg">
|
|
<div className="text-center p-8 max-w-md">
|
|
<div className="mx-auto w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center mb-4">
|
|
<Lock className="w-6 h-6 text-gray-400" />
|
|
</div>
|
|
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
Fonctionnalité {minPlan}+
|
|
</h3>
|
|
<p className="text-sm text-gray-600 mb-4">
|
|
Cette fonctionnalité nécessite le plan {minPlan} ou supérieur.
|
|
</p>
|
|
<Link
|
|
href="/pricing"
|
|
className="inline-flex items-center px-4 py-2 bg-brand-turquoise text-white text-sm font-medium rounded-lg hover:opacity-90 transition-opacity"
|
|
>
|
|
Voir les plans
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|