import React, { useState, useEffect } from 'react'; import { X, Save, RefreshCw } from 'lucide-react'; import { useUpdateBusiness } from '../../../hooks/usePlatform'; import { useSubscriptionPlans } from '../../../hooks/usePlatformSettings'; import { PlatformBusiness } from '../../../api/platform'; import FeaturesPermissionsEditor, { PERMISSION_DEFINITIONS, getPermissionKey } from '../../../components/platform/FeaturesPermissionsEditor'; // Default tier settings - used when no subscription plans are loaded const TIER_DEFAULTS: Record = { FREE: { max_users: 2, max_resources: 5, can_manage_oauth_credentials: false, can_accept_payments: false, can_use_custom_domain: false, can_white_label: false, can_api_access: false, }, STARTER: { max_users: 5, max_resources: 15, can_manage_oauth_credentials: false, can_accept_payments: true, can_use_custom_domain: false, can_white_label: false, can_api_access: false, }, PROFESSIONAL: { max_users: 15, max_resources: 50, can_manage_oauth_credentials: false, can_accept_payments: true, can_use_custom_domain: true, can_white_label: false, can_api_access: true, }, ENTERPRISE: { max_users: -1, // unlimited max_resources: -1, // unlimited can_manage_oauth_credentials: true, can_accept_payments: true, can_use_custom_domain: true, can_white_label: true, can_api_access: true, }, }; interface BusinessEditModalProps { business: PlatformBusiness | null; isOpen: boolean; onClose: () => void; } const BusinessEditModal: React.FC = ({ business, isOpen, onClose }) => { const updateBusinessMutation = useUpdateBusiness(); const { data: subscriptionPlans } = useSubscriptionPlans(); const [editForm, setEditForm] = useState({ name: '', is_active: true, subscription_tier: 'FREE', // Limits max_users: 5, max_resources: 10, // Platform Permissions (flat, matching backend model) can_manage_oauth_credentials: false, can_accept_payments: false, can_use_custom_domain: false, can_white_label: false, can_api_access: false, // Feature permissions (flat, matching backend model) can_add_video_conferencing: false, can_connect_to_api: false, can_book_repeated_events: true, can_require_2fa: false, can_download_logs: false, can_delete_data: false, can_use_sms_reminders: false, can_use_masked_phone_numbers: false, can_use_pos: false, can_use_mobile_app: false, can_export_data: false, can_use_plugins: true, can_use_tasks: true, can_create_plugins: false, can_use_webhooks: false, can_use_calendar_sync: false, can_use_contracts: false, can_process_refunds: false, can_create_packages: false, can_use_email_templates: false, can_customize_booking_page: false, advanced_reporting: false, priority_support: false, dedicated_support: false, sso_enabled: false, }); // Get tier defaults from subscription plans or fallback to static defaults const getTierDefaults = (tier: string) => { // Try to find matching subscription plan if (subscriptionPlans) { const tierNameMap: Record = { 'FREE': 'Free', 'STARTER': 'Starter', 'PROFESSIONAL': 'Professional', 'ENTERPRISE': 'Enterprise', }; const plan = subscriptionPlans.find(p => p.business_tier === tierNameMap[tier] || p.business_tier === tier ); if (plan) { const staticDefaults = TIER_DEFAULTS[tier] || TIER_DEFAULTS.FREE; return { // Limits max_users: plan.limits?.max_users ?? staticDefaults.max_users, max_resources: plan.limits?.max_resources ?? staticDefaults.max_resources, // Platform Permissions can_manage_oauth_credentials: plan.permissions?.can_manage_oauth_credentials ?? staticDefaults.can_manage_oauth_credentials, can_accept_payments: plan.permissions?.can_accept_payments ?? staticDefaults.can_accept_payments, can_use_custom_domain: plan.permissions?.can_use_custom_domain ?? staticDefaults.can_use_custom_domain, can_white_label: plan.permissions?.can_white_label ?? staticDefaults.can_white_label, can_api_access: plan.permissions?.can_api_access ?? staticDefaults.can_api_access, // Feature permissions (flat, matching backend model) can_add_video_conferencing: plan.permissions?.video_conferencing ?? false, can_connect_to_api: plan.permissions?.can_api_access ?? false, can_book_repeated_events: true, can_require_2fa: false, can_download_logs: false, can_delete_data: false, can_use_sms_reminders: plan.permissions?.sms_reminders ?? false, can_use_masked_phone_numbers: plan.permissions?.masked_calling ?? false, can_use_pos: false, can_use_mobile_app: false, can_export_data: plan.permissions?.export_data ?? false, can_use_plugins: plan.permissions?.plugins ?? true, can_use_tasks: plan.permissions?.tasks ?? true, can_create_plugins: plan.permissions?.can_create_plugins ?? false, can_use_webhooks: plan.permissions?.webhooks ?? false, can_use_calendar_sync: plan.permissions?.calendar_sync ?? false, }; } } // Fallback to static defaults const staticDefaults = TIER_DEFAULTS[tier] || TIER_DEFAULTS.FREE; return { ...staticDefaults, can_add_video_conferencing: false, can_connect_to_api: staticDefaults.can_api_access, can_book_repeated_events: true, can_require_2fa: false, can_download_logs: false, can_delete_data: false, can_use_sms_reminders: false, can_use_masked_phone_numbers: false, can_use_pos: false, can_use_mobile_app: false, can_export_data: false, can_use_plugins: true, can_use_tasks: true, can_create_plugins: false, can_use_webhooks: false, can_use_calendar_sync: false, }; }; // Handle subscription tier change - auto-update limits and permissions const handleTierChange = (newTier: string) => { const defaults = getTierDefaults(newTier); setEditForm(prev => ({ ...prev, subscription_tier: newTier, ...defaults, })); }; // Reset to tier defaults button handler const handleResetToTierDefaults = () => { const defaults = getTierDefaults(editForm.subscription_tier); setEditForm(prev => ({ ...prev, ...defaults, })); }; // Update form when business changes useEffect(() => { if (business) { const b = business as any; setEditForm({ name: business.name, is_active: business.is_active, subscription_tier: business.tier, // Limits max_users: business.max_users || 5, max_resources: business.max_resources || 10, // Platform Permissions (flat, matching backend) can_manage_oauth_credentials: business.can_manage_oauth_credentials || false, can_accept_payments: b.can_accept_payments || false, can_use_custom_domain: b.can_use_custom_domain || false, can_white_label: b.can_white_label || false, can_api_access: b.can_api_access || false, // Feature permissions (flat, matching backend) can_add_video_conferencing: b.can_add_video_conferencing || false, can_connect_to_api: b.can_connect_to_api || false, can_book_repeated_events: b.can_book_repeated_events ?? true, can_require_2fa: b.can_require_2fa || false, can_download_logs: b.can_download_logs || false, can_delete_data: b.can_delete_data || false, can_use_sms_reminders: b.can_use_sms_reminders || false, can_use_masked_phone_numbers: b.can_use_masked_phone_numbers || false, can_use_pos: b.can_use_pos || false, can_use_mobile_app: b.can_use_mobile_app || false, can_export_data: b.can_export_data || false, can_use_plugins: b.can_use_plugins ?? true, can_use_tasks: b.can_use_tasks ?? true, can_create_plugins: b.can_create_plugins || false, can_use_webhooks: b.can_use_webhooks || false, can_use_calendar_sync: b.can_use_calendar_sync || false, can_use_contracts: b.can_use_contracts || false, can_process_refunds: b.can_process_refunds || false, can_create_packages: b.can_create_packages || false, can_use_email_templates: b.can_use_email_templates || false, can_customize_booking_page: b.can_customize_booking_page || false, advanced_reporting: b.advanced_reporting || false, priority_support: b.priority_support || false, dedicated_support: b.dedicated_support || false, sso_enabled: b.sso_enabled || false, }); } }, [business]); const handleEditSave = () => { if (!business) return; updateBusinessMutation.mutate( { businessId: business.id, data: editForm, }, { onSuccess: () => { onClose(); }, } ); }; if (!isOpen || !business) return null; return (
{/* Modal Header */}

Edit Business: {business.name}

{/* Modal Body */}
{/* Business Name */}
setEditForm({ ...editForm, name: e.target.value })} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" />
{/* Status */}

Inactive businesses cannot be accessed

{/* Subscription Tier */}

Changing tier will auto-update limits and permissions to tier defaults

{/* Limits Configuration */}

Limits Configuration

Use -1 for unlimited. These limits control what this business can create.

setEditForm({ ...editForm, max_users: parseInt(e.target.value) || 0 })} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" />
setEditForm({ ...editForm, max_resources: parseInt(e.target.value) || 0 })} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" />
{/* Features & Permissions - Using unified FeaturesPermissionsEditor */}
typeof v === 'boolean') ) as Record} onChange={(key, value) => { setEditForm(prev => ({ ...prev, [key]: value })); }} headerTitle="Features & Permissions" />
{/* Modal Footer */}
); }; export default BusinessEditModal;