diff --git a/src/pages/AdminUserDetail.tsx b/src/pages/AdminUserDetail.tsx index 4026da6..c920a43 100644 --- a/src/pages/AdminUserDetail.tsx +++ b/src/pages/AdminUserDetail.tsx @@ -1818,312 +1818,327 @@ export default function AdminUserDetail() { )} - {/* Panel Info */} - {panelInfoLoading ? ( -
-
-
- ) : panelInfo && !panelInfo.found ? ( -
- {t('admin.users.detail.panelNotFound')} -
- ) : panelInfo && panelInfo.found ? ( + {/* Panel Info, Traffic, Devices — only inside subscription detail */} + {(subscriptionDetailView || userSubscriptions.length <= 1) && ( <> - {/* Links */} - {(panelInfo.subscription_url || panelInfo.happ_link) && ( -
-
- {t('admin.users.detail.subscriptionUrl')} / {t('admin.users.detail.happLink')} -
-
- {panelInfo.subscription_url && ( - - )} - {panelInfo.happ_link && ( - - )} -
+ {panelInfoLoading ? ( +
+
- )} - - {/* Config */} - {(panelInfo.trojan_password || panelInfo.vless_uuid || panelInfo.ss_password) && ( -
-
- {t('admin.users.detail.panelConfig')} -
-
- {panelInfo.trojan_password && ( - - )} - {panelInfo.vless_uuid && ( - - )} - {panelInfo.ss_password && ( - - )} -
+ ) : panelInfo && !panelInfo.found ? ( +
+ {t('admin.users.detail.panelNotFound')}
- )} - - {/* Connection info */} -
-
-
-
- {t('admin.users.detail.firstConnected')} -
-
- {formatDate(panelInfo.first_connected_at)} -
-
-
-
- {t('admin.users.detail.lastOnline')} -
-
{formatDate(panelInfo.online_at)}
-
- {panelInfo.last_connected_node_name && ( -
-
- {t('admin.users.detail.lastNode')} + ) : panelInfo && panelInfo.found ? ( + <> + {/* Links */} + {(panelInfo.subscription_url || panelInfo.happ_link) && ( +
+
+ {t('admin.users.detail.subscriptionUrl')} /{' '} + {t('admin.users.detail.happLink')}
-
- {panelInfo.last_connected_node_name} +
+ {panelInfo.subscription_url && ( + + )} + {panelInfo.happ_link && ( + + )}
)} -
-
- {/* Live traffic */} -
-
- {t('admin.users.detail.liveTraffic')} -
-
-
- - {formatBytes(panelInfo.used_traffic_bytes)} - - - {panelInfo.traffic_limit_bytes > 0 - ? formatBytes(panelInfo.traffic_limit_bytes) - : '∞'} - -
-
-
0 - ? `${Math.min(100, (panelInfo.used_traffic_bytes / panelInfo.traffic_limit_bytes) * 100)}%` - : '0%', - }} - /> -
-
-
- {t('admin.users.detail.lifetime')}:{' '} - {formatBytes(panelInfo.lifetime_used_traffic_bytes)} -
-
+ {/* Config */} + {(panelInfo.trojan_password || + panelInfo.vless_uuid || + panelInfo.ss_password) && ( +
+
+ {t('admin.users.detail.panelConfig')} +
+
+ {panelInfo.trojan_password && ( + + )} + {panelInfo.vless_uuid && ( + + )} + {panelInfo.ss_password && ( + + )} +
+
+ )} - {/* Node usage */} + {/* Connection info */} +
+
+
+
+ {t('admin.users.detail.firstConnected')} +
+
+ {formatDate(panelInfo.first_connected_at)} +
+
+
+
+ {t('admin.users.detail.lastOnline')} +
+
+ {formatDate(panelInfo.online_at)} +
+
+ {panelInfo.last_connected_node_name && ( +
+
+ {t('admin.users.detail.lastNode')} +
+
+ {panelInfo.last_connected_node_name} +
+
+ )} +
+
+ + {/* Live traffic */} +
+
+ {t('admin.users.detail.liveTraffic')} +
+
+
+ + {formatBytes(panelInfo.used_traffic_bytes)} + + + {panelInfo.traffic_limit_bytes > 0 + ? formatBytes(panelInfo.traffic_limit_bytes) + : '∞'} + +
+
+
0 + ? `${Math.min(100, (panelInfo.used_traffic_bytes / panelInfo.traffic_limit_bytes) * 100)}%` + : '0%', + }} + /> +
+
+
+ {t('admin.users.detail.lifetime')}:{' '} + {formatBytes(panelInfo.lifetime_used_traffic_bytes)} +
+
+ + {/* Node usage */} +
+
+ + {t('admin.users.detail.nodeUsage')} + +
+
+ {[1, 3, 7, 14, 30].map((d) => ( + + ))} +
+ +
+
+ {nodeUsageForPeriod.length > 0 ? ( +
+ {nodeUsageForPeriod.map((item) => { + const maxBytes = nodeUsageForPeriod[0].total_bytes; + const pct = maxBytes > 0 ? (item.total_bytes / maxBytes) * 100 : 0; + return ( +
+
+ + {item.country_code && ( + + {getCountryFlag(item.country_code)} + + )} + {item.node_name} + + + {formatBytes(item.total_bytes)} + +
+
+
+
+
+ ); + })} +
+ ) : ( +
-
+ )} +
+ + ) : null} + + {/* Devices */}
- {t('admin.users.detail.nodeUsage')} + {t('admin.users.detail.devices.title')} ({devicesTotal}/{deviceLimit})
-
- {[1, 3, 7, 14, 30].map((d) => ( - - ))} -
+ {devices.length > 0 && ( + + )}
- {nodeUsageForPeriod.length > 0 ? ( + {devicesLoading ? ( +
+
+
+ ) : devices.length > 0 ? (
- {nodeUsageForPeriod.map((item) => { - const maxBytes = nodeUsageForPeriod[0].total_bytes; - const pct = maxBytes > 0 ? (item.total_bytes / maxBytes) * 100 : 0; - return ( -
-
- - {item.country_code && ( - {getCountryFlag(item.country_code)} - )} - {item.node_name} - - {formatBytes(item.total_bytes)} + {devices.map((device) => ( +
+
+
+ {device.platform || device.device_model || device.hwid.slice(0, 12)}
-
-
+
+ {device.device_model && device.platform && ( + {device.device_model} + )} + {device.hwid.slice(0, 8)}... + {device.created_at && ( + + {new Date(device.created_at).toLocaleDateString(locale)} + + )}
- ); - })} + +
+ ))}
) : ( -
-
+
+ {t('admin.users.detail.devices.none')} +
)}
- ) : null} - - {/* Devices */} -
-
- - {t('admin.users.detail.devices.title')} ({devicesTotal}/{deviceLimit}) - -
- - {devices.length > 0 && ( - - )} -
-
- {devicesLoading ? ( -
-
-
- ) : devices.length > 0 ? ( -
- {devices.map((device) => ( -
-
-
- {device.platform || device.device_model || device.hwid.slice(0, 12)} -
-
- {device.device_model && device.platform && ( - {device.device_model} - )} - {device.hwid.slice(0, 8)}... - {device.created_at && ( - {new Date(device.created_at).toLocaleDateString(locale)} - )} -
-
- -
- ))} -
- ) : ( -
- {t('admin.users.detail.devices.none')} -
- )} -
+ )}
)}