Loading dashboard...
No data available.
} + + {status && ( +OS Uptime: {formatUptime(status.uptime)}
+App Uptime: {formatUptime(status.appStats.uptime)}
+Load Avg: {status.loads?.join(' / ')}
+CPU Cores: {status.cpuCores} ({status.logicalPro} logical)
+CPU Speed: {toFixedIfNecessary(status.cpuSpeedMhz,0)} MHz
+Not available
}Upload: {formatBytes(status.netIO.up)}/s
Download: {formatBytes(status.netIO.down)}/s
Total Sent: {formatBytes(status.netTraffic.sent)}
Total Received: {formatBytes(status.netTraffic.recv)}
TCP: {status.tcpCount}
UDP: {status.udpCount}
IPv4: {status.publicIP.ipv4 || 'N/A'}
IPv6: {status.publicIP.ipv6 || 'N/A'}
No clients configured for this inbound.
} + {inbound?.protocol === 'shadowsocks' && ++ For Shadowsocks, client configuration (method and password) is part of the main inbound settings. + The QR code / subscription link below uses these global settings. +
+ } + + {(displayClients.length > 0 || inbound?.protocol === 'shadowsocks') && ( +Email / Identifier | + {(inbound?.protocol !== 'shadowsocks') &&{getClientIdentifierLabel(inbound?.protocol)} | } +Traffic (Up/Down) | +Quota | +Expiry | +Status | +Actions | +
---|---|---|---|---|---|---|
{inbound.remark || 'Shadowsocks Settings'} | +{formatBytes(inbound.up || 0)} / {formatBytes(inbound.down || 0)} | +{inbound.total > 0 ? formatBytes(inbound.total) : 'Unlimited'} | +{inbound.expiryTime > 0 ? new Date(inbound.expiryTime).toLocaleDateString() : 'Never'} | ++ {inbound.enable ? Enabled : Disabled } + | ++ + {/* No Edit/Delete/Reset for SS "client" as it's part of inbound config */} + | +|
{client.email} | +{getClientIdentifier(client, inbound?.protocol)} | +{formatBytes(client.up || 0)} / {formatBytes(client.down || 0)} | ++ { (client.totalGB !== undefined && client.totalGB > 0) ? formatBytes(client.totalGB * 1024 * 1024 * 1024) : (client.actualTotal !== undefined && client.actualTotal > 0) ? formatBytes(client.actualTotal) : 'Unlimited' } + | ++ {client.actualExpiryTime && client.actualExpiryTime > 0 ? new Date(client.actualExpiryTime).toLocaleDateString() : client.expiryTime && client.expiryTime > 0 ? new Date(client.expiryTime).toLocaleDateString() + " (Def)" : 'Never'} + | ++ {client.enableClientStat === undefined ? 'N/A' : client.enableClientStat ? + Enabled : + Disabled + } + | ++ + + + + | +
No clients configured for this inbound.
} + + {displayClients.length > 0 && ( +{getClientIdentifierLabel(inbound?.protocol)} | } +Traffic (Up/Down) | +Quota | +Expiry | +Status | +Actions | +|
---|---|---|---|---|---|---|
{client.email} | + {canManageClients &&{getClientIdentifier(client, inbound?.protocol)} | } +{formatBytes(client.up || 0)} / {formatBytes(client.down || 0)} | ++ { (client.totalGB !== undefined && client.totalGB > 0) ? formatBytes(client.totalGB * 1024 * 1024 * 1024) : (client.actualTotal !== undefined && client.actualTotal > 0) ? formatBytes(client.actualTotal) : 'Unlimited' } + | ++ {client.actualExpiryTime && client.actualExpiryTime > 0 ? new Date(client.actualExpiryTime).toLocaleDateString() : client.expiryTime && client.expiryTime > 0 ? new Date(client.expiryTime).toLocaleDateString() + " (Def)" : 'Never'} + | ++ {client.enableClientStat === undefined ? 'N/A' : client.enableClientStat ? + Enabled : + Disabled + } + | ++ {canManageClients && } + {canManageClients && + + } + + {canManageClients && (client.id || client.password) && } + | +
No inbounds found.
} + + {inbounds.length > 0 && ( +Remark | +Protocol | +Port / Listen | +Traffic (Up/Down) | +Quota | +Expiry | +Status | +Actions | +
---|---|---|---|---|---|---|---|
{inbound.remark || 'N/A'} | +{inbound.protocol} | +{inbound.port}{inbound.listen ? ` (${inbound.listen})` : ''} | +{formatBytes(inbound.up)} / {formatBytes(inbound.down)} | +{inbound.total > 0 ? formatBytes(inbound.total) : 'Unlimited'} | ++ {inbound.expiryTime === 0 ? 'Never' : new Date(inbound.expiryTime).toLocaleDateString()} + | +
+ |
+ + Edit + + {/* Placeholder for Manage Clients/Details */} + Clients + | +
Experience a fresh new look and feel.
+ + Go to Dashboard + +Loading settings data...
; + + switch(activeTab) { + case 'panel': + returnPlease select a settings category.
Current Xray Version: {currentXrayVersion || 'Unknown'}
+ {isLoadingVersions &&Loading versions...
} + {!isLoadingVersions && xrayVersions.length === 0 && !error &&No versions found or failed to load.
} +Manage GeoIP and GeoSite files.
+Version: {version}
} + {state === 'error' && errorMsg && ( ++ Error: {errorMsg.length > 100 ? errorMsg.substring(0, 97) + "..." : errorMsg} +
+ )} +{formError}
} + +
+ Note: The server address used ("YOUR_SERVER_IP_OR_DOMAIN") is a placeholder.
+ For this link to work, ensure your actual server address/domain is correctly configured in the generation logic
+ (src/lib/subscriptionLink.ts
) or, ideally, fetched from panel settings in a future update.
+
Could not generate subscription link for this client/protocol combination.
+ )} + +Email: {client.email}
+{clientIdentifierLabel} {clientIdentifierField === 'id' ? client.id : client.password}
+ {client.flow && protocol === 'vless' &&Flow: {client.flow}
} + {client.totalGB !== undefined &&Quota: {client.totalGB > 0 ? `${client.totalGB} GB` : 'Unlimited'}
} + {client.expiryTime !== undefined &&Expiry: {client.expiryTime > 0 ? new Date(client.expiryTime).toLocaleDateString() : 'Never'}
} + {client.limitIp !== undefined &&IP Limit: {client.limitIp > 0 ? client.limitIp : 'Unlimited'}
} +No clients configured. Click "Add Client" to begin.
} + {clients.map((client, index) => ( +{error}
} ++ Edit the JSON details for the selected network/security type here. + The 'network' and 'security' fields above will be included in the final JSON. +
+ ++ Click the toggle to change 2FA status. This change requires saving all settings. + If enabling for the first time, save settings, then the QR code and token will appear. +
+ + {twoFactorEnable && twoFactorToken && otpUrl && ( +Scan this QR code with your authenticator app:
+Or manually enter this token:
+{twoFactorToken}
++ Important: Store this token securely. If you lose access to your authenticator app, you may lose access to your account. +
++ 2FA is marked as enabled, but no token is available. Please save settings. + The panel may need a restart for the token to be generated if this is the first time enabling. +
+ )} +Loading logs...
} + {error &&{error}
} + + {!isLoading && !error && logs.length === 0 &&No logs to display with current filters.
} + + {!isLoading && logs.length > 0 && ( +