feat: introduce a new configuration system with dedicated pages for S2A and email settings.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
||||
import type { AppConfig } from '../types'
|
||||
import { defaultConfig } from '../types'
|
||||
import { loadConfig, saveConfig } from '../utils/storage'
|
||||
import { saveConfig } from '../utils/storage'
|
||||
import { S2AClient } from '../api/s2a'
|
||||
|
||||
interface ConfigContextValue {
|
||||
@@ -14,6 +14,7 @@ interface ConfigContextValue {
|
||||
isConnected: boolean
|
||||
testConnection: () => Promise<boolean>
|
||||
s2aClient: S2AClient | null
|
||||
refreshConfig: () => Promise<void>
|
||||
}
|
||||
|
||||
const ConfigContext = createContext<ConfigContextValue | null>(null)
|
||||
@@ -23,24 +24,37 @@ export function ConfigProvider({ children }: { children: ReactNode }) {
|
||||
const [isConnected, setIsConnected] = useState(false)
|
||||
const [s2aClient, setS2aClient] = useState<S2AClient | null>(null)
|
||||
|
||||
// Load config from localStorage on mount
|
||||
useEffect(() => {
|
||||
const savedConfig = loadConfig()
|
||||
setConfig(savedConfig)
|
||||
|
||||
// Create S2A client if config is available
|
||||
if (savedConfig.s2a.apiBase && savedConfig.s2a.adminKey) {
|
||||
const client = new S2AClient({
|
||||
baseUrl: savedConfig.s2a.apiBase,
|
||||
apiKey: savedConfig.s2a.adminKey,
|
||||
})
|
||||
setS2aClient(client)
|
||||
|
||||
// Test connection on load
|
||||
client.testConnection().then(setIsConnected)
|
||||
// Load config from server on mount
|
||||
const refreshConfig = useCallback(async () => {
|
||||
try {
|
||||
const res = await fetch('/api/config')
|
||||
const data = await res.json()
|
||||
if (data.code === 0 && data.data) {
|
||||
const serverConfig = data.data
|
||||
setConfig(prev => ({
|
||||
...prev,
|
||||
s2a: {
|
||||
...prev.s2a,
|
||||
apiBase: serverConfig.s2a_api_base || '',
|
||||
adminKey: serverConfig.s2a_admin_key || '',
|
||||
},
|
||||
pooling: {
|
||||
...prev.pooling,
|
||||
concurrency: serverConfig.concurrency || 2,
|
||||
priority: serverConfig.priority || 0,
|
||||
groupIds: serverConfig.group_ids || [],
|
||||
},
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load config from server:', error)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
refreshConfig()
|
||||
}, [refreshConfig])
|
||||
|
||||
// Update S2A client when config changes
|
||||
useEffect(() => {
|
||||
if (config.s2a.apiBase && config.s2a.adminKey) {
|
||||
@@ -110,8 +124,9 @@ export function ConfigProvider({ children }: { children: ReactNode }) {
|
||||
const testConnection = useCallback(async (): Promise<boolean> => {
|
||||
try {
|
||||
// 使用后端代理 API 来测试 S2A 连接(避免 CORS 问题)
|
||||
const res = await fetch('http://localhost:8088/api/s2a/test')
|
||||
const connected = res.ok
|
||||
const res = await fetch('/api/s2a/test')
|
||||
const data = await res.json()
|
||||
const connected = data.code === 0
|
||||
setIsConnected(connected)
|
||||
return connected
|
||||
} catch {
|
||||
@@ -132,6 +147,7 @@ export function ConfigProvider({ children }: { children: ReactNode }) {
|
||||
isConnected,
|
||||
testConnection,
|
||||
s2aClient,
|
||||
refreshConfig,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user