Files
sub2api/frontend/src/i18n/locales/en/admin/resources.ts
T

521 lines
21 KiB
TypeScript

export default {
scheduledTests: {
title: 'Scheduled Tests',
addPlan: 'Add Plan',
editPlan: 'Edit Plan',
deletePlan: 'Delete Plan',
model: 'Model',
cronExpression: 'Cron Expression',
enabled: 'Enabled',
lastRun: 'Last Run',
nextRun: 'Next Run',
maxResults: 'Max Results',
noPlans: 'No scheduled test plans',
confirmDelete: 'Are you sure you want to delete this plan?',
createSuccess: 'Plan created successfully',
updateSuccess: 'Plan updated successfully',
deleteSuccess: 'Plan deleted successfully',
results: 'Test Results',
noResults: 'No test results yet',
responseText: 'Response',
errorMessage: 'Error',
success: 'Success',
failed: 'Failed',
running: 'Running',
schedule: 'Schedule',
cronHelp: 'Standard 5-field cron expression (e.g., */30 * * * *)',
cronTooltipTitle: 'Cron expression examples:',
cronTooltipMeaning: 'Defines when the test runs automatically. The 5 fields are: minute, hour, day, month, and weekday.',
cronTooltipExampleEvery30Min: '*/30 * * * *: run every 30 minutes',
cronTooltipExampleHourly: '0 * * * *: run at the start of every hour',
cronTooltipExampleDaily: '0 9 * * *: run every day at 09:00',
cronTooltipExampleWeekly: '0 9 * * 1: run every Monday at 09:00',
cronTooltipRange: 'Recommended range: use standard 5-field cron. For health checks, start with a moderate frequency such as every 30 minutes, every hour, or once a day instead of running too often.',
maxResultsTooltipTitle: 'What Max Results means:',
maxResultsTooltipMeaning: 'Sets how many historical test results are kept for a single plan so the result list does not grow without limit.',
maxResultsTooltipBody: 'Only the newest test results are kept. Once the number of saved results exceeds this value, older records are pruned automatically so the history list and storage stay under control.',
maxResultsTooltipExample: 'For example, 100 means keeping at most the latest 100 test results. When the 101st result is saved, the oldest one is removed.',
maxResultsTooltipRange: 'Recommended range: usually 20 to 200. Use 20-50 when you only care about recent health status, or 100-200 if you want a longer trend history.',
autoRecover: 'Auto Recover',
autoRecoverHelp: 'Automatically recover account from error/rate-limited state on successful test'
},
// Proxies
proxies: {
title: 'Proxy Management',
description: 'Manage proxy servers for accounts',
createProxy: 'Create Proxy',
editProxy: 'Edit Proxy',
deleteProxy: 'Delete Proxy',
ad: {
inline: 'Need proxy IP?'
},
dataImport: 'Import',
dataExportSelected: 'Export Selected',
dataImportTitle: 'Import Proxies',
dataImportHint: 'Upload the exported proxy JSON file to import proxies in bulk.',
dataImportWarning: 'Import will create or reuse proxies, keep their status, and trigger latency checks after completion.',
dataImportFile: 'Data File',
dataImportButton: 'Start Import',
dataImporting: 'Importing...',
dataImportSelectFile: 'Please select a data file',
dataImportParseFailed: 'Failed to parse data',
dataImportFailed: 'Failed to import data',
dataImportResult: 'Import Result',
dataImportResultSummary: 'Created {proxy_created}, reused {proxy_reused}, failed {proxy_failed}',
dataImportErrors: 'Failure Details',
dataImportSuccess: 'Import completed: created {proxy_created}, reused {proxy_reused}',
dataImportCompletedWithErrors: 'Import completed with errors: failed {proxy_failed}',
dataExport: 'Export',
dataExportConfirmMessage: 'The exported data contains sensitive proxy information. Store it securely.',
dataExportConfirm: 'Confirm Export',
dataExported: 'Data exported successfully',
dataExportFailed: 'Failed to export data',
copyProxyUrl: 'Copy Proxy URL',
urlCopied: 'Proxy URL copied',
searchProxies: 'Search proxies...',
allProtocols: 'All Protocols',
allStatus: 'All Status',
protocols: {
http: 'HTTP',
https: 'HTTPS',
socks5: 'SOCKS5',
socks5h: 'SOCKS5H (Remote DNS)'
},
columns: {
name: 'Name',
protocol: 'Protocol',
address: 'Address',
auth: 'Auth',
location: 'Location',
status: 'Status',
accounts: 'Accounts',
latency: 'Latency',
expiry: 'Validity',
createdAt: 'Created',
actions: 'Actions'
},
testConnection: 'Test Connection',
qualityCheck: 'Quality Check',
batchQualityCheck: 'Batch Quality Check',
batchTest: 'Test All Proxies',
testFailed: 'Failed',
latencyFailed: 'Connection failed',
batchTestEmpty: 'No proxies available for testing',
batchTestDone: 'Batch test completed for {count} proxies',
batchTestFailed: 'Batch test failed',
batchDeleteAction: 'Delete',
batchDelete: 'Batch delete',
batchDeleteConfirm: 'Delete {count} selected proxies? In-use ones will be skipped.',
batchDeleteDone: 'Deleted {deleted} proxies, skipped {skipped}',
batchDeleteSkipped: 'Skipped {skipped} proxies',
batchDeleteFailed: 'Batch delete failed',
deleteBlockedInUse: 'This proxy is in use and cannot be deleted',
accountsTitle: 'Accounts using this IP',
accountsEmpty: 'No accounts are using this proxy',
accountsFailed: 'Failed to load accounts list',
accountName: 'Account',
accountPlatform: 'Platform',
accountNotes: 'Notes',
name: 'Name',
protocol: 'Protocol',
host: 'Host',
port: 'Port',
username: 'Username (Optional)',
password: 'Password (Optional)',
status: 'Status',
enterProxyName: 'Enter proxy name',
leaveEmptyToKeep: 'Leave empty to keep current',
optionalAuth: 'Optional authentication',
form: {
hostPlaceholder: 'proxy.example.com',
portPlaceholder: '8080'
},
noProxiesYet: 'No proxies yet',
createFirstProxy: 'Create your first proxy to route traffic through it.',
// Batch import
standardAdd: 'Standard Add',
batchAdd: 'Quick Add',
batchInput: 'Proxy List',
batchInputPlaceholder:
"Enter one proxy per line in the following formats:\nsocks5://user:pass{'@'}192.168.1.1:1080\nhttp://192.168.1.1:8080\nhttps://user:pass{'@'}proxy.example.com:443",
batchInputHint:
"Supports http, https, socks5 protocols. Format: protocol://[user:pass{'@'}]host:port",
parsedCount: '{count} valid',
invalidCount: '{count} invalid',
duplicateCount: '{count} duplicate',
importing: 'Importing...',
importProxies: 'Import {count} proxies',
batchImportSuccess: 'Successfully imported {created} proxies, skipped {skipped} duplicates',
batchImportAllSkipped: 'All {skipped} proxies already exist, skipped import',
failedToImport: 'Failed to batch import',
// Other messages
creating: 'Creating...',
updating: 'Updating...',
proxyCreated: 'Proxy created successfully',
proxyUpdated: 'Proxy updated successfully',
proxyDeleted: 'Proxy deleted successfully',
proxyWorking: 'Proxy is working!',
proxyWorkingWithLatency: 'Proxy is working! Latency: {latency}ms',
proxyTestFailed: 'Proxy test failed',
qualityCheckDone: 'Quality check completed: score {score} ({grade})',
qualityCheckFailed: 'Failed to run proxy quality check',
batchQualityDone:
'Batch quality check completed for {count} proxies: healthy {healthy}, warn {warn}, challenge {challenge}, abnormal {failed}',
batchQualityFailed: 'Batch quality check failed',
batchQualityEmpty: 'No proxies available for quality check',
qualityReportTitle: 'Proxy Quality Report',
qualityGrade: 'Grade {grade}',
qualityExitIP: 'Exit IP',
qualityCountry: 'Exit Region',
qualityBaseLatency: 'Base Latency',
qualityCheckedAt: 'Checked At',
qualityTableTarget: 'Target',
qualityTableStatus: 'Status',
qualityTableLatency: 'Latency',
qualityTableMessage: 'Message',
qualityInline: 'Quality {grade}/{score}',
qualityStatusHealthy: 'Healthy',
qualityStatusPass: 'Pass',
qualityStatusWarn: 'Warn',
qualityStatusFail: 'Fail',
qualityStatusChallenge: 'Challenge',
qualityTargetBase: 'Base Connectivity',
failedToLoad: 'Failed to load proxies',
failedToCreate: 'Failed to create proxy',
failedToUpdate: 'Failed to update proxy',
failedToDelete: 'Failed to delete proxy',
failedToTest: 'Failed to test proxy',
nameRequired: 'Please enter proxy name',
hostRequired: 'Please enter host address',
portInvalid: 'Port must be between 1-65535',
deleteConfirm:
"Are you sure you want to delete '{name}'? Accounts using this proxy will have their proxy removed.",
neverExpires: 'Never',
expired: 'Expired',
overdueDays: 'Overdue {days}d',
expiringInDays: 'Expires in {days}d',
remainingDays: '{days}d left',
expiresAt: 'Validity',
nDays: '{days}d',
expiryDaysPlaceholder: 'Custom days, empty = never',
expiryWarnDays: 'Expiry warning (days)',
fallbackMode: 'Failure fallback',
fallbackNone: 'No fallback',
fallbackProxy: 'Backup proxy',
fallbackDirect: 'Direct connection',
backupProxy: 'Backup proxy',
},
// Redeem Codes
redeem: {
title: 'Redeem Code Management',
description: 'Generate and manage redeem codes',
generateCodes: 'Generate Codes',
searchCodes: 'Search codes or email...',
allTypes: 'All Types',
allStatus: 'All Status',
balance: 'Balance',
concurrency: 'Concurrency',
subscription: 'Subscription',
invitation: 'Invitation',
invitationHint: 'Invitation codes are used to restrict user registration. They are automatically marked as used after use.',
unused: 'Unused',
used: 'Used',
columns: {
code: 'Code',
type: 'Type',
value: 'Value',
status: 'Status',
usedBy: 'Used By',
usedAt: 'Used At',
expiresAt: 'Expires At',
actions: 'Actions'
},
userPrefix: 'User #{id}',
exportCsv: 'Export CSV',
batchUpdate: 'Batch Update',
batchUpdateTitle: 'Batch Update Redeem Codes',
selectedCount: '{count} redeem code(s) selected',
clearSelection: 'Clear selection',
selectCodesFirst: 'Select redeem codes first',
noBatchFieldsSelected: 'Select at least one field to update',
batchUpdateSuccess: 'Updated {count} redeem code(s)',
failedToBatchUpdate: 'Failed to batch update redeem codes',
batchFields: {
status: 'Status',
expiresAt: 'Expires At',
notes: 'Notes',
group: 'Group'
},
batchNotesPlaceholder: 'Enter the new note, or leave blank to clear it',
clearGroup: 'Clear group',
deleteAllUnused: 'Delete All Unused Codes',
deleteCode: 'Delete Redeem Code',
deleteCodeConfirm:
'Are you sure you want to delete this redeem code? This action cannot be undone.',
deleteAllUnusedConfirm:
'Are you sure you want to delete all unused (active) redeem codes? This action cannot be undone.',
deleteAll: 'Delete All',
generateCodesTitle: 'Generate Redeem Codes',
generatedSuccessfully: 'Generated Successfully',
codesCreated: '{count} redeem code(s) created',
codeType: 'Code Type',
amount: 'Amount ($)',
value: 'Value',
count: 'Count',
generating: 'Generating...',
generate: 'Generate',
copyAll: 'Copy All',
copied: 'Copied!',
download: 'Download',
codesExported: 'Codes exported successfully',
codeDeleted: 'Redeem code deleted successfully',
codesDeleted: 'Successfully deleted {count} unused code(s)',
noUnusedCodes: 'No unused codes to delete',
failedToLoad: 'Failed to load redeem codes',
failedToGenerate: 'Failed to generate codes',
failedToExport: 'Failed to export codes',
failedToDelete: 'Failed to delete code',
failedToDeleteUnused: 'Failed to delete unused codes',
failedToCopy: 'Failed to copy codes',
types: {
balance: 'Balance',
concurrency: 'Concurrency',
subscription: 'Subscription',
invitation: 'Invitation',
// Admin adjustment types (created when admin modifies user balance/concurrency)
admin_balance: 'Balance (Admin)',
admin_concurrency: 'Concurrency (Admin)'
},
selectGroup: 'Select Group',
selectGroupPlaceholder: 'Choose a subscription group',
validityDays: 'Validity Days',
codeExpiry: 'Code Expiry',
neverExpires: 'Never expires',
expiryPresetDays: '{days} days',
customExpiry: 'Custom',
customExpiryDays: 'Custom days',
expiryDaysRequired: 'Please enter a valid expiry day count',
groupRequired: 'Please select a subscription group',
days: ' days',
status: {
unused: 'Unused',
used: 'Used',
expired: 'Expired',
disabled: 'Disabled'
}
},
// Announcements
announcements: {
title: 'Announcements',
description: 'Create announcements and target by conditions',
createAnnouncement: 'Create Announcement',
editAnnouncement: 'Edit Announcement',
deleteAnnouncement: 'Delete Announcement',
searchAnnouncements: 'Search announcements...',
status: 'Status',
allStatus: 'All Status',
columns: {
title: 'Title',
status: 'Status',
notifyMode: 'Notify Mode',
targeting: 'Targeting',
timeRange: 'Schedule',
createdAt: 'Created At',
actions: 'Actions'
},
statusLabels: {
draft: 'Draft',
active: 'Active',
archived: 'Archived'
},
notifyModeLabels: {
silent: 'Silent',
popup: 'Popup'
},
form: {
title: 'Title',
content: 'Content (Markdown supported)',
status: 'Status',
notifyMode: 'Notify Mode',
notifyModeHint: 'Popup mode will show a popup notification to users',
startsAt: 'Starts At',
endsAt: 'Ends At',
startsAtHint: 'Leave empty to start immediately',
endsAtHint: 'Leave empty to never expire',
targetingMode: 'Targeting',
targetingAll: 'All users',
targetingCustom: 'Custom rules',
addOrGroup: 'Add OR group',
addAndCondition: 'Add AND condition',
conditionType: 'Condition type',
conditionSubscription: 'Subscription',
conditionBalance: 'Balance',
operator: 'Operator',
balanceValue: 'Balance threshold',
selectPackages: 'Select packages'
},
operators: {
gt: '>',
gte: '≥',
lt: '<',
lte: '≤',
eq: '='
},
targetingSummaryAll: 'All users',
targetingSummaryCustom: 'Custom ({groups} groups)',
timeImmediate: 'Immediate',
timeNever: 'Never',
readStatus: 'Read Status',
eligible: 'Eligible',
readAt: 'Read at',
unread: 'Unread',
searchUsers: 'Search users...',
failedToLoad: 'Failed to load announcements',
failedToCreate: 'Failed to create announcement',
failedToUpdate: 'Failed to update announcement',
failedToDelete: 'Failed to delete announcement',
failedToLoadReadStatus: 'Failed to load read status',
deleteConfirm: 'Are you sure you want to delete this announcement? This action cannot be undone.'
},
// Promo Codes
promo: {
title: 'Promo Code Management',
description: 'Create and manage registration promo codes',
createCode: 'Create Promo Code',
editCode: 'Edit Promo Code',
deleteCode: 'Delete Promo Code',
searchCodes: 'Search codes...',
allStatus: 'All Status',
columns: {
code: 'Code',
bonusAmount: 'Bonus Amount',
maxUses: 'Max Uses',
usedCount: 'Used',
usage: 'Usage',
status: 'Status',
expiresAt: 'Expires At',
createdAt: 'Created At',
actions: 'Actions'
},
// Form labels (flat structure for template usage)
code: 'Promo Code',
autoGenerate: 'auto-generate if empty',
codePlaceholder: 'Enter promo code or leave empty',
bonusAmount: 'Bonus Amount ($)',
maxUses: 'Max Uses',
zeroUnlimited: '0 = unlimited',
expiresAt: 'Expires At',
notes: 'Notes',
notesPlaceholder: 'Optional notes for this code',
status: 'Status',
neverExpires: 'Never expires',
// Status labels
statusActive: 'Active',
statusDisabled: 'Disabled',
statusExpired: 'Expired',
statusMaxUsed: 'Used Up',
// Usage records
usageRecords: 'Usage Records',
viewUsages: 'View Usages',
noUsages: 'No usage records yet',
userPrefix: 'User #{id}',
copied: 'Copied!',
// Messages
noCodesYet: 'No promo codes yet',
createFirstCode: 'Create your first promo code to offer registration bonuses.',
codeCreated: 'Promo code created successfully',
codeUpdated: 'Promo code updated successfully',
codeDeleted: 'Promo code deleted successfully',
deleteCodeConfirm: 'Are you sure you want to delete this promo code? This action cannot be undone.',
copyRegisterLink: 'Copy register link',
registerLinkCopied: 'Register link copied to clipboard',
failedToLoad: 'Failed to load promo codes',
failedToCreate: 'Failed to create promo code',
failedToUpdate: 'Failed to update promo code',
failedToDelete: 'Failed to delete promo code',
failedToLoadUsages: 'Failed to load usage records'
},
// Usage Records
usage: {
title: 'Usage Records',
description: 'View and manage all user usage records',
userFilter: 'User',
searchUserPlaceholder: 'Search user by email...',
searchApiKeyPlaceholder: 'Search API key by name...',
searchAccountPlaceholder: 'Search account by name...',
selectedUser: 'Selected',
user: 'User',
account: 'Account',
group: 'Group',
requestId: 'Request ID',
requestIdCopied: 'Request ID copied',
allModels: 'All Models',
allAccounts: 'All Accounts',
allGroups: 'All Groups',
allTypes: 'All Types',
inputCost: 'Input Cost',
outputCost: 'Output Cost',
cacheCreationCost: 'Cache Creation Cost',
cacheReadCost: 'Cache Read Cost',
inputTokens: 'Input Tokens',
outputTokens: 'Output Tokens',
cacheCreationTokens: 'Cache Creation Tokens',
cacheCreation5mTokens: 'Cache Write',
cacheCreation1hTokens: 'Cache Write',
cacheReadTokens: 'Cache Read Tokens',
failedToLoad: 'Failed to load usage records',
billingType: 'Billing Type',
allBillingTypes: 'All Billing Types',
billingTypeBalance: 'Balance',
billingTypeSubscription: 'Subscription',
billingMode: 'Billing Mode',
billingModeToken: 'Token',
billingModePerRequest: 'Per Request',
billingModeImage: 'Image',
allBillingModes: 'All Billing Modes',
ipAddress: 'IP',
clickToViewBalance: 'Click to view balance history',
failedToLoadUser: 'Failed to load user info',
userDeletedBadge: 'Deleted',
cleanup: {
button: 'Cleanup',
title: 'Cleanup Usage Records',
warning: 'Cleanup is irreversible and will affect historical stats.',
submit: 'Submit Cleanup',
submitting: 'Submitting...',
confirmTitle: 'Confirm Cleanup',
confirmMessage: 'Are you sure you want to submit this cleanup task? This action cannot be undone.',
confirmSubmit: 'Confirm Cleanup',
cancel: 'Cancel',
cancelConfirmTitle: 'Confirm Cancel',
cancelConfirmMessage: 'Are you sure you want to cancel this cleanup task?',
cancelConfirm: 'Confirm Cancel',
cancelSuccess: 'Cleanup task canceled',
cancelFailed: 'Failed to cancel cleanup task',
recentTasks: 'Recent Cleanup Tasks',
loadingTasks: 'Loading tasks...',
noTasks: 'No cleanup tasks yet',
range: 'Range',
deletedRows: 'Deleted',
missingRange: 'Please select a date range',
submitSuccess: 'Cleanup task created',
submitFailed: 'Failed to create cleanup task',
loadFailed: 'Failed to load cleanup tasks',
status: {
pending: 'Pending',
running: 'Running',
succeeded: 'Succeeded',
failed: 'Failed',
canceled: 'Canceled'
}
}
},
// Ops Monitoring
}