import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Badge } from '@/components/ui/badge'; import { AdminLayout } from '@/components/layout/AdminLayout'; import { useAuth } from '@/hooks/useAuth'; import { useUserRole } from '@/hooks/useUserRole'; import { useAdminSettings } from '@/hooks/useAdminSettings'; import { NovuMigrationUtility } from '@/components/admin/NovuMigrationUtility'; import { TestDataGenerator } from '@/components/admin/TestDataGenerator'; import { IntegrationTestRunner } from '@/components/admin/IntegrationTestRunner'; import { Loader2, Save, Clock, Users, Bell, Shield, Settings, Trash2, Plug, AlertTriangle, Lock, TestTube, RefreshCw, Info, AlertCircle } from 'lucide-react'; import { useDocumentTitle } from '@/hooks/useDocumentTitle'; export default function AdminSettings() { useDocumentTitle('Settings - Admin'); const { user } = useAuth(); const { isSuperuser, loading: roleLoading } = useUserRole(); const { settings, isLoading, error, updateSetting, isUpdating, getSettingsByCategory } = useAdminSettings(); if (roleLoading || isLoading) { return (
); } if (!user || !isSuperuser()) { return (

Access Denied

You don't have permission to access admin settings.

{error && (
Error details: {error.message}
)}
); } if (!settings || settings.length === 0) { return (

No Settings Found

No admin settings have been configured yet. Please contact your system administrator.

{error && (
Error details: {error.message}
)}
); } const SettingInput = ({ setting }: { setting: any }) => { const [localValue, setLocalValue] = useState(setting.setting_value); const handleSubmit = async () => { await updateSetting(setting.setting_key, localValue); }; // Auto-flagging threshold settings if (setting.setting_key === 'moderation.auto_flag_threshold') { return (

Content will be automatically flagged for review after receiving this many reports

Current: {localValue} reports
); } // Review retention settings if (setting.setting_key === 'moderation.review_retention_days') { return (

How long to keep moderated content data before automatic cleanup

Current: {localValue} days
); } // Ban duration settings if (setting.setting_key === 'moderation.ban_durations') { const [banDurations, setBanDurations] = useState<{[key: string]: number}>( typeof localValue === 'object' ? localValue : { temporary: 7, extended: 30, permanent: 0 } ); const updateBanDuration = (type: string, days: number) => { const updated = { ...banDurations, [type]: days }; setBanDurations(updated); setLocalValue(updated); }; const [savingBanDurations, setSavingBanDurations] = useState(false); const saveBanDurations = async () => { setSavingBanDurations(true); try { await updateSetting(setting.setting_key, banDurations); } finally { setSavingBanDurations(false); } }; return (

Configure the available ban duration options for moderators

Short-term restriction for minor violations

Longer restriction for serious violations

Indefinite restriction for severe violations

Permanent
); } // Admin panel refresh mode setting if (setting.setting_key === 'system.admin_panel_refresh_mode') { return (

Choose how the admin panel statistics refresh

Current: {(typeof localValue === 'string' ? localValue.replace(/"/g, '') : localValue) === 'auto' ? 'Auto-refresh' : 'Manual'}
); } // Admin panel poll interval setting if (setting.setting_key === 'system.admin_panel_poll_interval') { return (

How often to automatically refresh admin panel statistics (when auto-refresh is enabled)

Current: {localValue}s
); } // Auto-refresh strategy setting if (setting.setting_key === 'auto_refresh_strategy') { return (

How the moderation queue handles new items when they arrive

Current: {typeof localValue === 'string' ? localValue.replace(/"/g, '') : localValue}
); } // Retry settings if (setting.setting_key === 'retry.max_attempts') { return (

How many times to retry failed operations (entity/photo submissions)

Current: {localValue}
); } if (setting.setting_key === 'retry.base_delay') { return (

Milliseconds to wait before first retry attempt

Current: {localValue}ms
); } if (setting.setting_key === 'retry.max_delay') { return (

Maximum delay between retry attempts (exponential backoff cap)

Current: {localValue}ms
); } if (setting.setting_key === 'retry.backoff_multiplier') { return (

Growth rate for exponential backoff between retries

Current: {localValue}x
); } if (setting.setting_key === 'circuit_breaker.failure_threshold') { return (

Number of consecutive failures before blocking all requests temporarily

Current: {localValue}
); } if (setting.setting_key === 'circuit_breaker.reset_timeout') { return (

How long to wait before testing if service has recovered

Current: {Math.floor(Number(localValue) / 1000)}s
); } if (setting.setting_key === 'circuit_breaker.monitoring_window') { return (

Time window to track failures for circuit breaker

Current: {Math.floor(Number(localValue) / 60000)}min
); } // Helper to check if value is boolean const isBooleanSetting = (value: any) => { return value === true || value === false || value === 'true' || value === 'false'; }; // Boolean/switch settings - check by value type instead of key pattern if (isBooleanSetting(setting.setting_value)) { const getSettingIcon = () => { if (setting.setting_key.includes('email_alerts')) return ; if (setting.setting_key.includes('require_approval')) return ; if (setting.setting_key.includes('auto_cleanup')) return ; return ; }; return (
{getSettingIcon()}

{setting.setting_key.includes('email_alerts') && "Receive email notifications for this event"} {setting.setting_key.includes('require_approval') && "Items must be manually approved before being published"} {setting.setting_key.includes('auto_cleanup') && "Automatically remove old or rejected content"} {(!setting.setting_key.includes('email_alerts') && !setting.setting_key.includes('require_approval') && !setting.setting_key.includes('auto_cleanup')) && "Toggle this feature on or off"}

{localValue ? "Enabled" : "Disabled"} { setLocalValue(checked); updateSetting(setting.setting_key, checked); }} />
); } // Numeric threshold settings if (setting.setting_key.includes('threshold') || setting.setting_key.includes('limit') || setting.setting_key.includes('max_')) { return (

Set the numeric limit for this system parameter

{ const value = parseInt(e.target.value) || 0; setLocalValue(value); }} className="w-24" min="0" />
Current: {localValue}
); } // Default string input return (
{ setLocalValue(e.target.value); }} className="flex-1" />
); }; return (

Admin Settings

Configure system-wide settings and preferences

Moderation Users Notifications Resilience System Integrations Testing Integration Tests Moderation Settings Configure content moderation rules, thresholds, and automated actions {getSettingsByCategory('moderation').length > 0 ? ( getSettingsByCategory('moderation').map((setting) => ( )) ) : (

No moderation settings configured yet.

)}
User Management Configure user registration, profile settings, and account policies {getSettingsByCategory('user_management').length > 0 ? ( getSettingsByCategory('user_management').map((setting) => ( )) ) : (

No user management settings configured yet.

)}
Notification Settings Configure email alerts, push notifications, and communication preferences {getSettingsByCategory('notifications').length > 0 ? ( getSettingsByCategory('notifications').map((setting) => ( )) ) : (

No notification settings configured yet.

)}
Resilience & Retry Configuration Configure automatic retry behavior and circuit breaker settings for handling transient failures

About Retry & Circuit Breaker

  • Retry Logic: Automatically retries failed operations (network issues, timeouts)
  • Circuit Breaker: Prevents system overload by blocking requests during outages
  • When to adjust: Increase retries for unstable networks, decrease for fast-fail scenarios

Retry Settings

{getSettingsByCategory('system') .filter(s => s.setting_key.startsWith('retry.')) .map(setting => )}

Circuit Breaker Settings

{getSettingsByCategory('system') .filter(s => s.setting_key.startsWith('circuit_breaker.')) .map(setting => )}

Configuration Changes

Settings take effect immediately but may be cached for up to 5 minutes in active sessions. Consider monitoring error logs after changes to verify behavior.

System Configuration Configure system-wide settings, maintenance options, and technical parameters {getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).length > 0 ? ( getSettingsByCategory('system').filter(s => !s.setting_key.startsWith('retry.') && !s.setting_key.startsWith('circuit_breaker.')).map((setting) => ( )) ) : (

No system settings configured yet.

)}
Integration Settings Configure third-party integrations and external services {getSettingsByCategory('integrations').length > 0 ? ( getSettingsByCategory('integrations').map((setting) => ( )) ) : (

No integration settings configured yet.

)}
); }