修改面板大小
Some checks failed
Build Linux / Build Linux x86_64 (push) Has been cancelled
Build Test / Build Test (Linux) (push) Has been cancelled
Build Test / Build Test (Windows) (push) Has been cancelled
Build Test / Build Test (macOS) (push) Has been cancelled
Build for Open Source / build (Linux, ubuntu-22.04, ) (push) Has been cancelled
Build for Open Source / build (Windows, windows-latest, ) (push) Has been cancelled
Build for Open Source / build (macOS, macos-latest, ) (push) Has been cancelled
Release / build-linux (push) Has been cancelled
Release / build-macos (push) Has been cancelled
Build Test / Build Test Summary (push) Has been cancelled
Release / Create Release (push) Has been cancelled

This commit is contained in:
2025-09-11 00:18:11 +08:00
parent 3456f9e06d
commit 4cdb22788f

View File

@@ -385,21 +385,12 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
const isToggling = togglingEnable[station.id]; const isToggling = togglingEnable[station.id];
return ( return (
<div className="flex items-center gap-2">
<Switch <Switch
checked={enabled} checked={enabled}
disabled={isToggling} disabled={isToggling}
onCheckedChange={() => toggleEnableStatus(station.id, enabled)} onCheckedChange={() => toggleEnableStatus(station.id, enabled)}
className="data-[state=checked]:bg-green-500" className="data-[state=checked]:bg-green-500"
/> />
{isToggling ? (
<Badge variant="secondary" className="animate-pulse">{t('common.updating')}</Badge>
) : enabled ? (
<Badge variant="default" className="bg-green-500">{t('status.enabled')}</Badge>
) : (
<Badge variant="secondary">{t('status.disabled')}</Badge>
)}
</div>
); );
}; };
@@ -691,75 +682,95 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
) : ( ) : (
stations.map((station) => ( stations.map((station) => (
<Card key={station.id} className="relative"> <Card key={station.id} className="relative">
<CardHeader className="pb-3"> <CardHeader className="pb-2 pt-3 px-3">
<div className="flex justify-between items-start"> <div className="flex justify-between items-center">
<div> <div className="flex-1 min-w-0 mr-2">
<CardTitle className="text-lg">{station.name}</CardTitle> <CardTitle className="text-sm font-medium">{station.name}</CardTitle>
<CardDescription className="mt-1"> <CardDescription className="text-xs mt-0.5">
{getAdapterDisplayName(station.adapter)} {getAdapterDisplayName(station.adapter)}
</CardDescription> </CardDescription>
</div> </div>
<div className="flex items-center gap-1">
{getStatusBadge(station)} {getStatusBadge(station)}
<Button
variant="ghost"
size="icon"
className="h-8 w-8"
onClick={(e) => {
e.stopPropagation();
setSelectedStation(station);
setShowEditDialog(true);
}}
>
<Edit className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-red-500 hover:text-red-700"
onClick={(e) => {
e.stopPropagation();
openDeleteDialog(station);
}}
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div> </div>
</CardHeader> </CardHeader>
<CardContent> <CardContent className="pt-1 pb-3 px-3">
<div className="space-y-3"> <div className="space-y-2">
<div className="flex items-center text-sm text-muted-foreground"> <div className="flex items-center text-xs text-muted-foreground">
<Globe className="mr-2 h-4 w-4" /> <Globe className="mr-1.5 h-3 w-3" />
{station.api_url} <span className="truncate">{station.api_url}</span>
</div> </div>
{station.description && ( {station.description && (
<p className="text-sm text-muted-foreground"> <p className="text-xs text-muted-foreground line-clamp-2">
{station.description} {station.description}
</p> </p>
)} )}
{/* PackyCode 额度显示 */} {/* PackyCode 额度显示 */}
{station.adapter === 'packycode' && ( {station.adapter === 'packycode' && (
<div className="mt-3 p-3 bg-blue-50 dark:bg-blue-950/30 rounded-lg border border-blue-200 dark:border-blue-900"> <div className="mt-2 p-2 bg-blue-50 dark:bg-blue-950/30 rounded-lg border border-blue-200 dark:border-blue-900">
{loadingQuota[station.id] ? ( {loadingQuota[station.id] ? (
<div className="flex items-center justify-center py-2"> <div className="flex items-center justify-center py-1">
<div className="h-4 w-4 animate-spin rounded-full border-b-2 border-blue-600"></div> <div className="h-3 w-3 animate-spin rounded-full border-b-2 border-blue-600"></div>
<span className="ml-2 text-sm text-muted-foreground">...</span> <span className="ml-2 text-xs text-muted-foreground">...</span>
</div> </div>
) : quotaData[station.id] ? ( ) : quotaData[station.id] ? (
<div className="space-y-3"> <div className="space-y-2">
{/* 用户信息和计划 */} {/* 用户信息和计划 */}
<div className="flex items-center justify-between text-xs"> <div className="flex items-center justify-between text-xs">
<div className="flex items-center gap-2"> <div className="flex items-center gap-1.5">
{quotaData[station.id].username && ( {quotaData[station.id].username && (
<span className="text-muted-foreground">{quotaData[station.id].username}</span> <span className="text-muted-foreground">{quotaData[station.id].username}</span>
)} )}
<Badge variant="secondary" className="text-xs"> <Badge variant="secondary" className="text-xs h-5 px-1.5">
{quotaData[station.id].plan_type.toUpperCase()} {quotaData[station.id].plan_type.toUpperCase()}
</Badge> </Badge>
{quotaData[station.id].opus_enabled && ( {quotaData[station.id].opus_enabled && (
<Badge variant="default" className="text-xs bg-purple-600"> <Badge variant="default" className="text-xs h-5 px-1.5 bg-purple-600">
Opus Opus
</Badge> </Badge>
)} )}
</div> </div>
{quotaData[station.id].plan_expires_at && (
<span className="text-muted-foreground">
: {new Date(quotaData[station.id].plan_expires_at!).toLocaleDateString()}
</span>
)}
</div> </div>
{/* 账户余额 */} {/* 账户余额 */}
<div className="flex items-center justify-between text-sm"> <div className="flex items-center justify-between text-xs">
<span className="text-muted-foreground">:</span> <span className="text-muted-foreground">:</span>
<span className="font-semibold text-blue-600"> <span className="font-medium text-blue-600">
${Number(quotaData[station.id].balance_usd).toFixed(2)} ${Number(quotaData[station.id].balance_usd).toFixed(2)}
</span> </span>
</div> </div>
{/* 日额度 */} {/* 日额度 */}
<div className="space-y-1"> <div className="space-y-0.5">
<div className="flex items-center justify-between text-sm"> <div className="flex items-center justify-between text-xs">
<span className="text-muted-foreground">:</span> <span className="text-muted-foreground">:</span>
<div className="flex items-center gap-2"> <div className="flex items-center gap-1">
{(() => { {(() => {
const daily_spent = Number(quotaData[station.id].daily_spent_usd); const daily_spent = Number(quotaData[station.id].daily_spent_usd);
const daily_budget = Number(quotaData[station.id].daily_budget_usd); const daily_budget = Number(quotaData[station.id].daily_budget_usd);
@@ -768,8 +779,7 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
<span className={daily_spent > daily_budget * 0.8 ? 'text-orange-600' : 'text-green-600'}> <span className={daily_spent > daily_budget * 0.8 ? 'text-orange-600' : 'text-green-600'}>
${daily_spent.toFixed(2)} ${daily_spent.toFixed(2)}
</span> </span>
<span className="text-muted-foreground">/</span> <span className="text-muted-foreground">/ ${daily_budget.toFixed(2)}</span>
<span className="text-muted-foreground">${daily_budget.toFixed(2)}</span>
</> </>
); );
})()} })()}
@@ -839,7 +849,7 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
className="h-5 px-2 text-xs" className="h-6 px-2 text-xs"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
fetchPackycodeQuota(station.id); fetchPackycodeQuota(station.id);
@@ -850,14 +860,15 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
</div> </div>
</div> </div>
) : ( ) : (
<div className="text-center py-2"> <div className="text-center py-1">
<Button <Button
variant="outline" variant="ghost"
size="sm" size="sm"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
fetchPackycodeQuota(station.id); fetchPackycodeQuota(station.id);
}} }}
className="h-7 text-xs px-2"
> >
</Button> </Button>
@@ -866,30 +877,6 @@ const RelayStationManager: React.FC<RelayStationManagerProps> = ({ onBack }) =>
</div> </div>
)} )}
<div className="flex justify-end">
<Button
variant="ghost"
size="sm"
onClick={(e) => {
e.stopPropagation();
setSelectedStation(station);
setShowEditDialog(true);
}}
>
<Edit className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
onClick={(e) => {
e.stopPropagation();
openDeleteDialog(station);
}}
className="text-red-500 hover:text-red-700"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>