import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { TextInput, NumberInput, Switch, Button, Stack, Paper, Text, Loader, Group, Badge } from '@mantine/core'; import { alert } from '@app/components/toast'; import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal'; import { useRestartServer } from '@app/components/shared/config/useRestartServer'; import { useAdminSettings } from '@app/hooks/useAdminSettings'; import PendingBadge from '@app/components/shared/config/PendingBadge'; import apiClient from '@app/services/apiClient'; import { useLoginRequired } from '@app/hooks/useLoginRequired'; import LoginRequiredBanner from '@app/components/shared/config/LoginRequiredBanner'; interface FeaturesSettingsData { serverCertificate?: { enabled?: boolean; organizationName?: string; validity?: number; regenerateOnStartup?: boolean; }; } export default function AdminFeaturesSection() { const { t } = useTranslation(); const { loginEnabled, validateLoginEnabled, getDisabledStyles } = useLoginRequired(); const { restartModalOpened, showRestartModal, closeRestartModal, restartServer } = useRestartServer(); const { settings, setSettings, loading, saving, fetchSettings, saveSettings, isFieldPending, } = useAdminSettings({ sectionName: 'features', fetchTransformer: async () => { const systemResponse = await apiClient.get('/api/v1/admin/settings/section/system'); const systemData = systemResponse.data || {}; const result: any = { serverCertificate: systemData.serverCertificate || { enabled: true, organizationName: 'Stirling-PDF', validity: 365, regenerateOnStartup: false } }; // Map pending changes from system._pending.serverCertificate if (systemData._pending?.serverCertificate) { result._pending = { serverCertificate: systemData._pending.serverCertificate }; } return result; }, saveTransformer: (settings) => { const deltaSettings: Record = {}; if (settings.serverCertificate) { deltaSettings['system.serverCertificate.enabled'] = settings.serverCertificate.enabled; deltaSettings['system.serverCertificate.organizationName'] = settings.serverCertificate.organizationName; deltaSettings['system.serverCertificate.validity'] = settings.serverCertificate.validity; deltaSettings['system.serverCertificate.regenerateOnStartup'] = settings.serverCertificate.regenerateOnStartup; } return { sectionData: {}, deltaSettings }; } }); useEffect(() => { if (loginEnabled) { fetchSettings(); } }, [loginEnabled]); const handleSave = async () => { if (!validateLoginEnabled()) { return; } try { await saveSettings(); showRestartModal(); } catch (_error) { alert({ alertType: 'error', title: t('admin.error', 'Error'), body: t('admin.settings.saveError', 'Failed to save settings'), }); } }; const actualLoading = loginEnabled ? loading : false; if (actualLoading) { return ( ); } return (
{t('admin.settings.features.title', 'Features')} {t('admin.settings.features.description', 'Configure optional features and functionality.')}
{/* Server Certificate - Pro Feature */} {t('admin.settings.features.serverCertificate.label', 'Server Certificate')} PRO {t('admin.settings.features.serverCertificate.description', 'Configure server-side certificate generation for "Sign with Stirling-PDF" functionality')}
{t('admin.settings.features.serverCertificate.enabled.label', 'Enable Server Certificate')} {t('admin.settings.features.serverCertificate.enabled.description', 'Enable server-side certificate for "Sign with Stirling-PDF" option')}
{ if (!loginEnabled) return; setSettings({ ...settings, serverCertificate: { ...settings.serverCertificate, enabled: e.target.checked } }); }} disabled={!loginEnabled} styles={getDisabledStyles()} />
{t('admin.settings.features.serverCertificate.organizationName.label', 'Organization Name')} } description={t('admin.settings.features.serverCertificate.organizationName.description', 'Organization name for generated certificates')} value={settings.serverCertificate?.organizationName || 'Stirling-PDF'} onChange={(e) => setSettings({ ...settings, serverCertificate: { ...settings.serverCertificate, organizationName: e.target.value } })} placeholder="Stirling-PDF" disabled={!loginEnabled} />
{t('admin.settings.features.serverCertificate.validity.label', 'Certificate Validity (days)')} } description={t('admin.settings.features.serverCertificate.validity.description', 'Number of days the certificate will be valid')} value={settings.serverCertificate?.validity ?? 365} onChange={(value) => setSettings({ ...settings, serverCertificate: { ...settings.serverCertificate, validity: Number(value) } })} min={1} max={3650} disabled={!loginEnabled} />
{t('admin.settings.features.serverCertificate.regenerateOnStartup.label', 'Regenerate on Startup')} {t('admin.settings.features.serverCertificate.regenerateOnStartup.description', 'Generate new certificate on each application startup')}
{ if (!loginEnabled) return; setSettings({ ...settings, serverCertificate: { ...settings.serverCertificate, regenerateOnStartup: e.target.checked } }); }} disabled={!loginEnabled} styles={getDisabledStyles()} />
{/* Save Button */} {/* Restart Confirmation Modal */}
); }