@@ -149,11 +149,6 @@ const UserConfig = ({ config, role, refreshConfig }: UserConfigProps) => {
// 当前登录用户名
const currentUsername = getAuthInfoFromBrowserCookie ( ) ? . username || null ;
// 检测存储类型是否为 upstash
const isUpstashStorage =
typeof window !== 'undefined' &&
( window as any ) . RUNTIME_CONFIG ? . STORAGE_TYPE === 'upstash' ;
useEffect ( ( ) = > {
if ( config ? . UserConfig ) {
setUserSettings ( {
@@ -314,26 +309,19 @@ const UserConfig = ({ config, role, refreshConfig }: UserConfigProps) => {
< / h4 >
< div className = 'flex items-center justify-between' >
< label
className = { ` text-gray-700 dark:text-gray-300 ${ isUpstashStorage ? 'opacity-50' : ''
className = { ` text-gray-700 dark:text-gray-300
} ` }
>
允 许 新 用 户 注 册
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< button
onClick = { ( ) = >
! isUpstashStorage &&
toggleAllowRegister ( ! userSettings . enableRegistration )
}
disabled = { isUpstashStorage }
className = { ` relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${ userSettings . enableRegistration
? 'bg-green-600'
: 'bg-gray-200 dark:bg-gray-700'
} ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : '' } `}
} ` }
>
< span
className = { ` inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${ userSettings . enableRegistration
@@ -976,11 +964,6 @@ const CategoryConfig = ({
from : 'config' ,
} ) ;
// 检测存储类型是否为 upstash
const isUpstashStorage =
typeof window !== 'undefined' &&
( window as any ) . RUNTIME_CONFIG ? . STORAGE_TYPE === 'upstash' ;
// dnd-kit 传感器
const sensors = useSensors (
useSensor ( PointerSensor , {
@@ -1066,7 +1049,6 @@ const CategoryConfig = ({
} ;
const handleDragEnd = ( event : any ) = > {
if ( isUpstashStorage ) return ;
const { active , over } = event ;
if ( ! over || active . id === over . id ) return ;
const oldIndex = categories . findIndex (
@@ -1107,10 +1089,9 @@ const CategoryConfig = ({
className = 'hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors select-none'
>
< td
className = { ` px-2 py-4 ${ isUpstashStorage ? 'text-gray-200' : ' cursor-grab text-gray-400'
} ` }
className = " px-2 py-4 cursor-grab text-gray-400"
style = { { touchAction : 'none' } }
{ ... ( isUpstashStorage ? {} : { ...attributes , ...listeners }) }
{ ... { ...attributes , ...listeners }}
>
< GripVertical size = { 16 } / >
< / td >
@@ -1146,20 +1127,16 @@ const CategoryConfig = ({
< td className = 'px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2' >
< button
onClick = { ( ) = >
! isUpstashStorage &&
handleToggleEnable ( category . query , category . type )
}
disabled = { isUpstashStorage }
className = { ` inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium ${ isUpstashStorage
? 'bg-gray-400 cursor-not-allowed text-white '
: ! category . disabled
? 'bg-red-100 dark:bg-red-900/40 text-red-800 dark:text-red-300 hover:bg-red-200 dark:hover:bg-red-900/60'
: 'bg-green-100 dark:bg-green-900/40 text-green-800 dark:text-green-300 hover:bg-green-200 dark:hover:bg-green-900/60'
className = { ` inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium ${ ! category . disabled
? 'bg-red-100 dark:bg-red-900/40 text-red-800 dark:text-red-300 hover:bg-red-200 dark:hover:bg-red-900/60'
: 'bg-green-100 dark:bg-green-900/40 text-green-800 dark:text-green-300 hover:bg-green-200 dark:hover:bg-green-900/60 '
} transition-colors ` }
>
{ ! category . disabled ? '禁用' : '启用' }
< / button >
{ category . from !== 'config' && ! isUpstashStorage && (
{ category . from !== 'config' && (
< button
onClick = { ( ) = > handleDelete ( category . query , category . type ) }
className = 'inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 hover:bg-gray-200 dark:bg-gray-700/40 dark:hover:bg-gray-700/60 dark:text-gray-200 transition-colors'
@@ -1186,25 +1163,16 @@ const CategoryConfig = ({
< div className = 'flex items-center justify-between' >
< h4 className = 'text-sm font-medium text-gray-700 dark:text-gray-300' >
自 定 义 分 类 列 表
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 配 置 文 件 修 改 )
< / span >
) }
< / h4 >
< button
onClick = { ( ) = > ! isUpstashStorage && setShowAddForm ( ! showAddForm ) }
disabled = { isUpstashStorage }
className = { ` px-3 py-1 text-sm rounded-lg transition-colors ${ isUpstashStorage
? 'bg-gray-400 cursor-not-allowed text-white'
: 'bg-green-600 hover:bg-green-700 text-white'
} ` }
onClick = { ( ) = > setShowAddForm ( ! showAddForm ) }
className = "px-3 py-1 text-sm rounded-lg transition-colors bg-green-600 hover:bg-green-700 text-white"
>
{ showAddForm ? '取消' : '添加分类' }
< / button >
< / div >
{ showAddForm && ! isUpstashStorage && (
{ showAddForm && (
< div className = 'p-4 bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 space-y-4' >
< div className = 'grid grid-cols-1 sm:grid-cols-2 gap-4' >
< input
@@ -1275,7 +1243,7 @@ const CategoryConfig = ({
< / tr >
< / thead >
< DndContext
sensors = { isUpstashStorage ? [ ] : sensors}
sensors = { sensors }
collisionDetection = { closestCenter }
onDragEnd = { handleDragEnd }
autoScroll = { false }
@@ -1299,7 +1267,7 @@ const CategoryConfig = ({
< / div >
{ /* 保存排序按钮 */ }
{ orderChanged && ! isUpstashStorage && (
{ orderChanged && (
< div className = 'flex justify-end' >
< button
onClick = { handleSaveOrder }
@@ -1419,7 +1387,7 @@ const ConfigFileComponent = ({ config, refreshConfig }: { config: AdminConfig |
< h3 className = 'text-xl font-semibold text-gray-900 dark:text-gray-100' >
配 置 订 阅
< / h3 >
< div className = 'text-sm text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-700 px-3 py-1.5 rounded-full' >
< div className = 'text-sm text-gray-500 dark:text-gray-400 px-3 py-1.5 rounded-full' >
最 后 更 新 : { lastCheckTime ? new Date ( lastCheckTime ) . toLocaleString ( 'zh-CN' ) : '从未更新' }
< / div >
< / div >
@@ -1438,10 +1406,31 @@ const ConfigFileComponent = ({ config, refreshConfig }: { config: AdminConfig |
className = 'w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent transition-all duration-200 shadow-sm hover:border-gray-400 dark:hover:border-gray-500'
/ >
< p className = 'mt-2 text-xs text-gray-500 dark:text-gray-400' >
输 入 配 置 文 件 的 订 阅 地 址 , 支 持 JSON格式
输 入 配 置 文 件 的 订 阅 地 址 , 要 求 JSON 格 式 , 且 使 用 Base58 编 码
< / p >
< / div >
{ /* 拉取配置按钮 */ }
< div className = 'pt-2' >
< button
onClick = { handleFetchConfig }
disabled = { fetching || ! subscriptionUrl . trim ( ) }
className = { ` w-full px-6 py-3 rounded-lg font-medium transition-all duration-200 ${ fetching || ! subscriptionUrl . trim ( )
? 'bg-gray-300 dark:bg-gray-600 cursor-not-allowed text-gray-500 dark:text-gray-400'
: 'bg-green-600 hover:bg-green-700 text-white shadow-sm hover:shadow-md transform hover:-translate-y-0.5'
} ` }
>
{ fetching ? (
< div className = 'flex items-center justify-center gap-2' >
< div className = 'w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin' > < / div >
拉 取 中 …
< / div >
) : (
'拉取配置'
) }
< / button >
< / div >
{ /* 自动更新开关 */ }
< div className = 'flex items-center justify-between' >
< div >
@@ -1468,27 +1457,6 @@ const ConfigFileComponent = ({ config, refreshConfig }: { config: AdminConfig |
/ >
< / button >
< / div >
{ /* 拉取配置按钮 */ }
< div className = 'pt-2' >
< button
onClick = { handleFetchConfig }
disabled = { fetching || ! subscriptionUrl . trim ( ) }
className = { ` w-full px-6 py-3 rounded-lg font-medium transition-all duration-200 ${ fetching || ! subscriptionUrl . trim ( )
? 'bg-gray-300 dark:bg-gray-600 cursor-not-allowed text-gray-500 dark:text-gray-400'
: 'bg-green-600 hover:bg-green-700 text-white shadow-sm hover:shadow-md transform hover:-translate-y-0.5'
} ` }
>
{ fetching ? (
< div className = 'flex items-center justify-center gap-2' >
< div className = 'w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin' > < / div >
拉 取 中 …
< / div >
) : (
'拉取配置'
) }
< / button >
< / div >
< / div >
< / div >
@@ -1521,7 +1489,7 @@ const ConfigFileComponent = ({ config, refreshConfig }: { config: AdminConfig |
: 'bg-green-600 hover:bg-green-700 text-white'
} ` }
>
{ saving ? '保存中…' : '保存配置文件 ' }
{ saving ? '保存中…' : '保存' }
< / button >
< / div >
< / div >
@@ -1530,7 +1498,7 @@ const ConfigFileComponent = ({ config, refreshConfig }: { config: AdminConfig |
} ;
// 新增站点配置组件
const SiteConfigComponent = ( { config } : { config : AdminConfig | null } ) = > {
const SiteConfigComponent = ( { config , refreshConfig } : { config : AdminConfig | null ; refreshConfig : ( ) = > Promise < void > } ) = > {
const [ siteSettings , setSiteSettings ] = useState < SiteConfig > ( {
SiteName : '' ,
Announcement : '' ,
@@ -1595,11 +1563,6 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
}
} ;
// 检测存储类型是否为 upstash
const isUpstashStorage =
typeof window !== 'undefined' &&
( window as any ) . RUNTIME_CONFIG ? . STORAGE_TYPE === 'upstash' ;
useEffect ( ( ) = > {
if ( config ? . SiteConfig ) {
setSiteSettings ( {
@@ -1651,22 +1614,18 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
// 处理豆瓣数据源变化
const handleDoubanDataSourceChange = ( value : string ) = > {
if ( ! isUpstashStorage ) {
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanProxyType : value ,
} ) ) ;
}
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanProxyType : value ,
} ) ) ;
} ;
// 处理豆瓣图片代理变化
const handleDoubanImageProxyChange = ( value : string ) = > {
if ( ! isUpstashStorage ) {
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanImageProxyType : value ,
} ) ) ;
}
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanImageProxyType : value ,
} ) ) ;
} ;
// 保存站点配置
@@ -1685,6 +1644,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
}
showSuccess ( '保存成功, 请刷新页面' ) ;
await refreshConfig ( ) ;
} catch ( err ) {
showError ( err instanceof Error ? err . message : '保存失败' ) ;
} finally {
@@ -1705,55 +1665,37 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
{ /* 站点名称 */ }
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
站 点 名 称
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< input
type = 'text'
value = { siteSettings . SiteName }
onChange = { ( e ) = >
! isUpstashStorage &&
setSiteSettings ( ( prev ) = > ( { . . . prev , SiteName : e.target.value } ) )
}
disabled = { isUpstashStorage }
className = { ` w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent"
/ >
< / div >
{ /* 站点公告 */ }
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
站 点 公 告
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< textarea
value = { siteSettings . Announcement }
onChange = { ( e ) = >
! isUpstashStorage &&
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
Announcement : e.target.value ,
} ) )
}
disabled = { isUpstashStorage }
rows = { 3 }
className = { ` w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = " w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent"
/ >
< / div >
@@ -1761,24 +1703,16 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
< div className = 'space-y-3' >
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
豆 瓣 数 据 代 理
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< div className = 'relative' data-dropdown = 'douban-datasource' >
{ /* 自定义下拉选择框 */ }
< button
type = 'button'
onClick = { ( ) = > setIsDoubanDropdownOpen ( ! isDoubanDropdownOpen ) }
disabled = { isUpstashStorage }
className = { ` w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = "w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left"
>
{
doubanDataSourceOptions . find (
@@ -1796,7 +1730,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
< / div >
{ /* 下拉选项列表 */ }
{ isDoubanDropdownOpen && ! isUpstashStorage && (
{ isDoubanDropdownOpen && (
< div className = 'absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto' >
{ doubanDataSourceOptions . map ( ( option ) = > (
< button
@@ -1850,8 +1784,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
{ siteSettings . DoubanProxyType === 'custom' && (
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
豆 瓣 代 理 地 址
< / label >
@@ -1860,15 +1793,12 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
placeholder = '例如: https://proxy.example.com/fetch?url='
value = { siteSettings . DoubanProxy }
onChange = { ( e ) = >
! isUpstashStorage &&
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanProxy : e.target.value ,
} ) )
}
disabled = { isUpstashStorage }
className = { ` w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = "w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500"
/ >
< p className = 'mt-1 text-xs text-gray-500 dark:text-gray-400' >
自 定 义 代 理 服 务 器 地 址
@@ -1881,15 +1811,9 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
< div className = 'space-y-3' >
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
豆 瓣 图 片 代 理
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< div className = 'relative' data-dropdown = 'douban-image-proxy' >
{ /* 自定义下拉选择框 */ }
@@ -1900,9 +1824,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
! isDoubanImageProxyDropdownOpen
)
}
disabled = { isUpstashStorage }
className = { ` w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = "w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left"
>
{
doubanImageProxyTypeOptions . find (
@@ -1920,7 +1842,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
< / div >
{ /* 下拉选项列表 */ }
{ isDoubanImageProxyDropdownOpen && ! isUpstashStorage && (
{ isDoubanImageProxyDropdownOpen && (
< div className = 'absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto' >
{ doubanImageProxyTypeOptions . map ( ( option ) = > (
< button
@@ -1974,8 +1896,7 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
{ siteSettings . DoubanImageProxyType === 'custom' && (
< div >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
豆 瓣 图 片 代 理 地 址
< / label >
@@ -1984,15 +1905,12 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
placeholder = '例如: https://proxy.example.com/fetch?url='
value = { siteSettings . DoubanImageProxy }
onChange = { ( e ) = >
! isUpstashStorage &&
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DoubanImageProxy : e.target.value ,
} ) )
}
disabled = { isUpstashStorage }
className = { ` w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : ''
} ` }
className = "w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500"
/ >
< p className = 'mt-1 text-xs text-gray-500 dark:text-gray-400' >
自 定 义 图 片 代 理 服 务 器 地 址
@@ -2043,30 +1961,22 @@ const SiteConfigComponent = ({ config }: { config: AdminConfig | null }) => {
< div >
< div className = 'flex items-center justify-between' >
< label
className = { ` block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 ${ isUpstashStorage ? 'opacity-50' : ''
} ` }
className = " block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2"
>
禁 用 黄 色 过 滤 器
{ isUpstashStorage && (
< span className = 'ml-2 text-xs text-gray-500 dark:text-gray-400' >
( Upstash 环 境 下 请 通 过 环 境 变 量 修 改 )
< / span >
) }
< / label >
< button
type = 'button'
onClick = { ( ) = >
! isUpstashStorage &&
setSiteSettings ( ( prev ) = > ( {
. . . prev ,
DisableYellowFilter : ! prev . DisableYellowFilter ,
} ) )
}
disabled = { isUpstashStorage }
className = { ` relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 ${ siteSettings . DisableYellowFilter
? 'bg-green-600'
: 'bg-gray-200 dark:bg-gray-700'
} ${ isUpstashStorage ? 'opacity-50 cursor-not-allowed' : '' } `}
} ` }
>
< span
className = { ` inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${ siteSettings . DisableYellowFilter
@@ -2171,6 +2081,7 @@ function AdminPageClient() {
throw new Error ( ` 重置失败: ${ response . status } ` ) ;
}
showSuccess ( '重置成功,请刷新页面!' ) ;
await fetchConfig ( ) ;
} catch ( err ) {
showError ( err instanceof Error ? err . message : '重置失败' ) ;
}
@@ -2249,7 +2160,7 @@ function AdminPageClient() {
isExpanded = { expandedTabs . siteConfig }
onToggle = { ( ) = > toggleTab ( 'siteConfig' ) }
>
< SiteConfigComponent config = { config } / >
< SiteConfigComponent config = { config } refreshConfig = { fetchConfig } / >
< / CollapsibleTab >
< div className = 'space-y-4' >