feat(admin): super-admin user detail dashboard
Add a read-only User Detail dashboard for super admins, reachable by clicking a user name in the admin users list. Backend: new `admin` module aggregating existing domain services (no new entities). ADMIN-only endpoints under /api/v1/admin: overview (profile, account status, wallet balance, revenue, summary counts), wallet transactions, applications (incl. deleted/docked with restore eligibility), build/deploy errors, tickets with conversation, and a composite activity timeline. Adds BillingService.getRevenueSummary and guards against a wallet get-or-create race in the overview reads. Frontend: tabbed detail page (overview/applications/activity/errors/ tickets) with lazy per-tab queries; user names in the admin list link to it (admin only); fa/en i18n keys and response types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -794,6 +794,82 @@ const en: Dictionary = {
|
||||
roleUpdated: 'Role updated',
|
||||
passwordUpdated: 'Password updated',
|
||||
passwordFailed: 'Failed to update password',
|
||||
detail: {
|
||||
back: 'Back',
|
||||
notFound: 'User not found',
|
||||
loading: 'Loading…',
|
||||
viewDetails: 'View details',
|
||||
tabOverview: 'Overview',
|
||||
tabApplications: 'Applications',
|
||||
tabActivity: 'Activity',
|
||||
tabErrors: 'Errors',
|
||||
tabTickets: 'Tickets',
|
||||
accountStatus: 'Account status',
|
||||
basicInfo: 'Basic info',
|
||||
walletBalance: 'Wallet balance',
|
||||
revenue: 'Revenue generated',
|
||||
totalCharged: 'Total charged',
|
||||
totalRefunded: 'Total refunded',
|
||||
joinedAt: 'Joined',
|
||||
namespace: 'Namespace',
|
||||
recentTransactions: 'Recent transactions',
|
||||
noTransactions: 'No transactions yet.',
|
||||
countsTitle: 'Summary',
|
||||
appsTotal: 'Total applications',
|
||||
appsActive: 'Active apps',
|
||||
appsDeleted: 'Deleted / archived apps',
|
||||
managedServices: 'Managed services',
|
||||
optionalServices: 'Add-on services',
|
||||
deploymentsCount: 'Deployments',
|
||||
ticketsOpenCount: 'Open tickets',
|
||||
txType: 'Type',
|
||||
txAmount: 'Amount',
|
||||
txBalance: 'Balance after',
|
||||
txDesc: 'Description',
|
||||
txDate: 'Date',
|
||||
txTypes: { charge: 'Charge', deduction: 'Deduction', refund: 'Refund', gateway_payment: 'Gateway payment' },
|
||||
appName: 'Name',
|
||||
appType: 'Type',
|
||||
appStatus: 'Status',
|
||||
appExpires: 'Service expiry',
|
||||
appCreated: 'Created',
|
||||
appResources: 'Resources',
|
||||
activeApps: 'Active apps',
|
||||
deletedApps: 'Deleted / archived apps',
|
||||
noApps: 'No applications.',
|
||||
expired: 'Expired',
|
||||
remainingDays: '{n} days left',
|
||||
remainingHours: '{n} hours left',
|
||||
lifecycle: { active: 'Active', suspended: 'Suspended', pending_deletion: 'Pending deletion', docked: 'Archived', deleted: 'Deleted' },
|
||||
restore: { restorable: 'Restorable', recoverable: 'Recoverable with payment', none: 'Not restorable' },
|
||||
errorApp: 'Application',
|
||||
errorReason: 'Error reason',
|
||||
errorTime: 'Time',
|
||||
errorState: 'State',
|
||||
errorResolved: 'Resolved',
|
||||
errorOpen: 'Open',
|
||||
noErrors: 'No build/deploy errors.',
|
||||
noErrorMessage: 'No error message recorded.',
|
||||
viewLogs: 'View logs',
|
||||
hideLogs: 'Hide logs',
|
||||
buildLog: 'Build log',
|
||||
deployLog: 'Deploy log',
|
||||
noLog: 'No log available.',
|
||||
noActivity: 'No activity recorded.',
|
||||
activityTypes: { app_created: 'Application created', app_docked: 'Application archived', app_deleted: 'Application deleted', deployment: 'Deployment', transaction: 'Wallet transaction', ticket: 'Support ticket' },
|
||||
ticketSubject: 'Subject',
|
||||
ticketStatus: 'Status',
|
||||
ticketDept: 'Department',
|
||||
ticketPriority: 'Priority',
|
||||
ticketMessages: '{n} messages',
|
||||
noTickets: 'No tickets.',
|
||||
viewConversation: 'View conversation',
|
||||
hideConversation: 'Hide conversation',
|
||||
ticketStatuses: { open: 'Open', answered: 'Answered', waiting: 'Waiting', closed: 'Closed' },
|
||||
ticketDepts: { technical: 'Technical', sales: 'Sales' },
|
||||
ticketPriorities: { low: 'Low', medium: 'Medium', high: 'High' },
|
||||
senderRoles: { user: 'User', admin: 'Admin', technical: 'Technical support', sales: 'Sales' },
|
||||
},
|
||||
},
|
||||
pools: {
|
||||
title: 'Cluster Pools',
|
||||
|
||||
Reference in New Issue
Block a user