'use client'; import { useEffect, useState } from 'react'; import { useMutation, useQueryClient, type UseQueryResult, } from '@tanstack/react-query'; import { Globe, Loader2, Mail, Search, Server, Sparkles } from 'lucide-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 { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Badge } from '@/components/ui/badge'; import services from '@/lib/services'; import type { SystemConfig } from '@/lib/services/admin'; import { toast } from 'sonner'; import { useTranslations } from 'next-intl'; interface SystemTabProps { configs: Record; systemConfigsQuery: UseQueryResult; } export function SystemTab({ configs, systemConfigsQuery }: SystemTabProps) { const queryClient = useQueryClient(); const t = useTranslations('settings.system'); const [serverAddress, setServerAddress] = useState(''); const [siteName, setSiteName] = useState(''); const [smtpHost, setSmtpHost] = useState(''); const [smtpPort, setSmtpPort] = useState(''); const [smtpUsername, setSmtpUsername] = useState(''); const [smtpPassword, setSmtpPassword] = useState(''); const [smtpTestOpen, setSmtpTestOpen] = useState(false); const [smtpTestTo, setSmtpTestTo] = useState(''); const [smtpTestLog, setSmtpTestLog] = useState(''); const [smtpTestSuccess, setSmtpTestSuccess] = useState(null); const [smtpTestError, setSmtpTestError] = useState(''); useEffect(() => { if (systemConfigsQuery.data) { setServerAddress(configs['server_address']?.value || ''); setSiteName(configs['site_name']?.value || ''); setSmtpHost(configs['smtp_host']?.value || ''); setSmtpPort(configs['smtp_port']?.value || '587'); setSmtpUsername(configs['smtp_username']?.value || ''); setSmtpPassword(configs['smtp_password']?.value || ''); } }, [systemConfigsQuery.data, configs]); const handleDetectAddress = () => { if (typeof window !== 'undefined') { setServerAddress(window.location.origin); toast.success(t('addressAutoDetected')); } }; const updateConfigMutation = useMutation({ mutationFn: async ({ key, value }: { key: string; value: boolean }) => { const config = configs[key]; if (!config) { throw new Error(`缺少配置项: ${key}`); } await services.adminSystemConfig.updateSystemConfig(key, { value: value ? 'true' : 'false', description: config.description, }); }, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ['admin', 'system-configs'], }); await queryClient.invalidateQueries({ queryKey: ['public-config'] }); toast.success(t('configUpdated')); }, onError: (error: Error) => { toast.error(error.message || t('updateConfigFailed')); }, }); const saveSystemMutation = useMutation({ mutationFn: async () => { const currentAddrCfg = configs['server_address']; const currentSiteCfg = configs['site_name']; await Promise.all([ services.adminSystemConfig.updateSystemConfig('server_address', { value: serverAddress, description: currentAddrCfg?.description || '服务器地址', }), services.adminSystemConfig.updateSystemConfig('site_name', { value: siteName, description: currentSiteCfg?.description || '系统平台的展示名称', }), ]); }, onSuccess: async () => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ['admin', 'system-configs'], }), queryClient.invalidateQueries({ queryKey: ['public-config'] }), ]); toast.success(t('generalConfigSaved')); }, onError: (error: Error) => { toast.error(error.message || t('saveConfigFailed')); }, }); const handleSystemSave = (e: React.FormEvent) => { e.preventDefault(); saveSystemMutation.mutate(); }; const saveSmtpMutation = useMutation({ mutationFn: async () => { const updates = [ { key: 'smtp_host', value: smtpHost }, { key: 'smtp_port', value: smtpPort }, { key: 'smtp_username', value: smtpUsername }, { key: 'smtp_password', value: smtpPassword }, ]; for (const update of updates) { const currentCfg = configs[update.key]; if ( update.key === 'smtp_password' && (update.value === '' || update.value === '******') ) { // If already configured and sent empty or mask, skip updating it (keep existing) if (currentCfg && currentCfg.value === '******') { continue; } } await services.adminSystemConfig.updateSystemConfig(update.key, { value: update.value, description: currentCfg?.description || '', }); } }, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ['admin', 'system-configs'], }); toast.success(t('smtpConfigSaved')); }, onError: (error: Error) => { toast.error(error.message || t('saveConfigFailed')); }, }); const handleSmtpSave = (e: React.FormEvent) => { e.preventDefault(); saveSmtpMutation.mutate(); }; const testSmtpMutation = useMutation({ mutationFn: async () => { setSmtpTestLog(t('connectingTest')); setSmtpTestSuccess(null); setSmtpTestError(''); const res = await services.adminSystemConfig.testSMTP({ smtp_host: smtpHost, smtp_port: parseInt(smtpPort, 10) || 587, smtp_username: smtpUsername, smtp_password: smtpPassword, to: smtpTestTo, }); return res; }, onSuccess: (data) => { setSmtpTestLog(data.log); if (data.success) { setSmtpTestSuccess(true); toast.success(t('testEmailSent')); } else { setSmtpTestSuccess(false); setSmtpTestError(data.error || t('sendFailedCheckConfig')); toast.error(t('testEmailFailed')); } }, onError: (error: Error) => { setSmtpTestSuccess(false); setSmtpTestError(error.message || t('requestFailed')); setSmtpTestLog( (prev) => prev + `\n${t('requestError')} ${error.message}\n`, ); toast.error(error.message || t('testRequestFailed')); }, }); const handleSmtpTestSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!smtpTestTo) { toast.error(t('enterTargetEmail')); return; } testSmtpMutation.mutate(); }; const indexingEnabled = configs['search_engine_indexing_enabled']?.value === 'true'; return (
{/* 通用设置 */}
{t('generalSettings')} {t('generalSettingsDesc')}
setSiteName(e.target.value)} placeholder='例如: OpenFlare' className='border-dashed bg-card text-xs' />

{t('siteNameDesc')}

setServerAddress(e.target.value)} placeholder='例如: https://example.com' className='border-dashed bg-card text-xs' />

{t('serverAddressDesc')}

{t('searchEngineIndexing')} {indexingEnabled ? t('indexingAllowed') : t('indexingDenied')}

{t('searchEngineIndexingDesc')}

updateConfigMutation.mutate({ key: 'search_engine_indexing_enabled', value: checked, }) } />
{t('addressChangeWarning')}
{/* SMTP 邮件设置 */}
{t('smtpSettings')} {t('smtpSettingsDesc')}
setSmtpHost(e.target.value)} placeholder='例如: smtp.example.com' className='bg-card border-dashed text-xs' />
setSmtpPort(e.target.value)} placeholder='例如: 587 或 465' className='bg-card border-dashed text-xs' />
setSmtpUsername(e.target.value)} placeholder='例如: sender@example.com' className='bg-card border-dashed text-xs' />
setSmtpPassword(e.target.value)} placeholder={ configs['smtp_password']?.value === '******' ? t('smtpPasswordMasked') : t('smtpPasswordPlaceholder') } className='bg-card border-dashed text-xs' />
{t('smtpTestTitle')} {t('smtpTestDesc')}
setSmtpTestTo(e.target.value)} placeholder='例如: receiver@example.com' className='bg-card border-dashed text-xs' disabled={testSmtpMutation.isPending} />
{smtpTestLog && (
                  {smtpTestLog}
                
)} {smtpTestSuccess === true && (
{t('testSuccess')}
)} {smtpTestSuccess === false && (
{t('testFailed')}: {smtpTestError}
)}
); }