@microcosmmoney/portal-react 3.10.0 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/components/auction/auction-page.js +11 -9
  2. package/dist/components/dashboard/assets-summary.js +5 -3
  3. package/dist/components/dashboard/dashboard-overview.js +5 -2
  4. package/dist/components/dashboard/ecosystem-stats.js +7 -5
  5. package/dist/components/dashboard/lock-periods.js +3 -1
  6. package/dist/components/dashboard/market-overview-bar.js +8 -6
  7. package/dist/components/dashboard/mcc-token-stats.js +7 -5
  8. package/dist/components/dashboard/mcd-stats.js +7 -5
  9. package/dist/components/dashboard/mining-weight.js +3 -1
  10. package/dist/components/dashboard/minting-stats.js +5 -3
  11. package/dist/components/dashboard/my-mining.js +9 -7
  12. package/dist/components/dashboard/price-chart.js +4 -2
  13. package/dist/components/fragment/fragment-page.js +3 -1
  14. package/dist/components/income/manager-income-page.js +5 -3
  15. package/dist/components/lending/lending-page.js +3 -1
  16. package/dist/components/mcd/mcd-page.js +7 -5
  17. package/dist/components/mining/mining-page.js +5 -3
  18. package/dist/components/profile/email-change-card.js +5 -3
  19. package/dist/components/profile/profile-page.js +10 -8
  20. package/dist/components/profile/two-factor-settings.js +6 -4
  21. package/dist/components/queue/queue-status-page.js +4 -2
  22. package/dist/components/reincarnation/reincarnation-page.js +6 -2
  23. package/dist/components/rewards/rewards-page.js +5 -3
  24. package/dist/components/stations/station-list-page.js +10 -8
  25. package/dist/components/territory/territory-page.js +5 -3
  26. package/dist/components/voting/voting-page.js +3 -1
  27. package/dist/components/wallet/wallet-page.js +9 -6
  28. package/dist/i18n-context.d.ts +11 -0
  29. package/dist/i18n-context.js +59 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +6 -2
  32. package/package.json +1 -1
@@ -6,6 +6,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  const email_change_card_1 = require("./email-change-card");
10
11
  const two_factor_settings_1 = require("./two-factor-settings");
11
12
  const API_BASE = 'https://api.microcosm.money/v1';
@@ -17,6 +18,7 @@ const LEVEL_INFO = {
17
18
  admiral: { label: 'Admiral', description: 'Auto-minted System NFT (≥10 Sector)', color: 'text-red-400' },
18
19
  };
19
20
  function MicrocosmProfilePage({ walletSection, } = {}) {
21
+ const t = (0, i18n_context_1.useTranslations)('profile');
20
22
  const api = (0, auth_react_1.useMicrocosmApi)();
21
23
  const { getAccessToken } = (0, auth_react_1.useMicrocosmContext)();
22
24
  const authState = (0, auth_react_1.useAuth)();
@@ -78,11 +80,11 @@ function MicrocosmProfilePage({ walletSection, } = {}) {
78
80
  if (!file)
79
81
  return;
80
82
  if (!file.type.startsWith('image/')) {
81
- setError('Please select an image file');
83
+ setError(t('selectImageFile', 'Please select an image file'));
82
84
  return;
83
85
  }
84
86
  if (file.size > 2 * 1024 * 1024) {
85
- setError('Image must be under 2MB');
87
+ setError(t('imageTooLarge', 'Image must not exceed 2MB'));
86
88
  return;
87
89
  }
88
90
  setUploadingAvatar(true);
@@ -126,20 +128,20 @@ function MicrocosmProfilePage({ walletSection, } = {}) {
126
128
  }
127
129
  };
128
130
  if (loading) {
129
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Profile" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "Your account information" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Loading profile..." }) })] }));
131
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Profile') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'View and manage your personal information') })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: t('loadingProfile', 'Loading profile...') }) })] }));
130
132
  }
131
133
  const displayName = profile?.display_name || profile?.email?.split('@')[0] || 'user';
132
134
  const lvl = (levelData?.current_rank || levelData?.database_level || 'miner').toLowerCase();
133
135
  const lvlInfo = LEVEL_INFO[lvl] || LEVEL_INFO.miner;
134
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Profile" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "Your account information" })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-4 mb-6 pb-6 border-b border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative group", children: [profile?.avatar_url ? ((0, jsx_runtime_1.jsx)("img", { src: profile.avatar_url, alt: "", className: "h-20 w-20 rounded bg-neutral-800 border border-neutral-700 object-cover" })) : ((0, jsx_runtime_1.jsx)("div", { className: "h-20 w-20 rounded bg-cyan-400/20 border border-cyan-400/30 flex items-center justify-center text-cyan-400 text-3xl font-bold", children: displayName.charAt(0).toUpperCase() })), (0, jsx_runtime_1.jsx)("button", { onClick: () => fileInputRef.current?.click(), disabled: uploadingAvatar, className: "absolute inset-0 bg-black/50 rounded opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center text-white text-xs disabled:opacity-30", children: uploadingAvatar ? '...' : 'edit' }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/jpeg,image/png,image/gif,image/webp", onChange: handleAvatarChange, className: "hidden" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1", children: editing ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", value: editName, onChange: (e) => setEditName(e.target.value), className: "w-full bg-neutral-800 border border-neutral-600 rounded px-3 py-2 text-white text-sm focus:outline-none focus:border-cyan-400", placeholder: "Display name" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: handleSave, disabled: saving, className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: saving ? 'Saving...' : 'Save' }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
136
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Profile') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'View and manage your personal information') })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-4 mb-6 pb-6 border-b border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative group", children: [profile?.avatar_url ? ((0, jsx_runtime_1.jsx)("img", { src: profile.avatar_url, alt: "", className: "h-20 w-20 rounded bg-neutral-800 border border-neutral-700 object-cover" })) : ((0, jsx_runtime_1.jsx)("div", { className: "h-20 w-20 rounded bg-cyan-400/20 border border-cyan-400/30 flex items-center justify-center text-cyan-400 text-3xl font-bold", children: displayName.charAt(0).toUpperCase() })), (0, jsx_runtime_1.jsx)("button", { onClick: () => fileInputRef.current?.click(), disabled: uploadingAvatar, className: "absolute inset-0 bg-black/50 rounded opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center text-white text-xs disabled:opacity-30", children: uploadingAvatar ? '...' : t('edit', 'edit') }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/jpeg,image/png,image/gif,image/webp", onChange: handleAvatarChange, className: "hidden" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1", children: editing ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", value: editName, onChange: (e) => setEditName(e.target.value), className: "w-full bg-neutral-800 border border-neutral-600 rounded px-3 py-2 text-white text-sm focus:outline-none focus:border-cyan-400", placeholder: t('displayName', 'Display name') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: handleSave, disabled: saving, className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: saving ? t('saving', 'Saving...') : t('save', 'Save') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
135
137
  setEditName(profile?.display_name || '');
136
138
  setEditing(false);
137
- }, disabled: saving, className: "px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Cancel" })] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-lg text-white", children: displayName }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setEditing(true), className: "text-xs text-neutral-500 hover:text-cyan-400", children: "[edit]" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-neutral-400 mt-1", children: profile?.email || '(no email)' }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 mt-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-neutral-800 text-neutral-300 rounded text-xs border border-neutral-700", children: profile?.role || 'user' }), profile?.email_verified ? ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-green-900/30 text-green-400 rounded text-xs border border-green-800", children: "verified" })) : ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-red-900/30 text-red-400 rounded text-xs border border-red-800", children: "unverified" }))] })] })) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "UID" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-white font-mono break-all", children: profile?.uid || userInfo?.uid || '-' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Short ID" }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white font-mono", children: profile?.short_id || '-' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Created" }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: formatDate(profile?.created_at) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Last Login" }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: formatDate(profile?.last_login_at) })] })] })] }), levelData && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Level Status", children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between p-4 bg-neutral-800 rounded", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "CURRENT LEVEL" }), (0, jsx_runtime_1.jsx)("div", { className: `text-xl font-bold ${lvlInfo.color}`, children: lvlInfo.label }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: lvlInfo.description })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "HOLDINGS" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-white font-mono", children: ["S:", levelData.holdings?.station ?? 0, " M:", levelData.holdings?.matrix ?? 0, " Se:", levelData.holdings?.sector ?? 0, " Sy:", levelData.holdings?.system ?? 0] })] })] }), levelData.next_level_requirement && ((0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: "PROGRESS" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white text-sm font-mono", children: [levelData.progress_percent ?? 0, "%"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-900 rounded-full h-2", children: (0, jsx_runtime_1.jsx)("div", { className: "h-2 rounded-full bg-cyan-400 transition-all", style: { width: `${Math.min(levelData.progress_percent ?? 0, 100)}%` } }) }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-2", children: levelData.next_level_requirement.description || '' }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400 mt-1", children: [levelData.next_level_requirement.have, "/", levelData.next_level_requirement.need, ' ', levelData.next_level_requirement.tier, " \u2192 ", ' ', (0, jsx_runtime_1.jsx)("span", { className: "text-white", children: levelData.next_rank })] })] }))] }) })), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Email Verification", children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "STATUS" }), profile?.email_verified ? ((0, jsx_runtime_1.jsx)("div", { className: "text-green-400 text-sm", children: "Verified" })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-red-400 text-sm", children: "Unverified" }))] }), !profile?.email_verified && ((0, jsx_runtime_1.jsx)("button", { onClick: async () => {
139
+ }, disabled: saving, className: "px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('cancel', 'Cancel') })] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-lg text-white", children: displayName }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => setEditing(true), className: "text-xs text-neutral-500 hover:text-cyan-400", children: ["[", t('edit', 'edit'), "]"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-neutral-400 mt-1", children: profile?.email || t('noEmail', '(no email)') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 mt-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-neutral-800 text-neutral-300 rounded text-xs border border-neutral-700", children: profile?.role || t('normalUser', 'user') }), profile?.email_verified ? ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-green-900/30 text-green-400 rounded text-xs border border-green-800", children: t('verified', 'verified') })) : ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-0.5 bg-red-900/30 text-red-400 rounded text-xs border border-red-800", children: t('unverified', 'unverified') }))] })] })) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "UID" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-white font-mono break-all", children: profile?.uid || userInfo?.uid || '-' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('shortId', 'Short ID') }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white font-mono", children: profile?.short_id || '-' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('created', 'Created') }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: formatDate(profile?.created_at) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('lastLogin', 'Last Login') }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: formatDate(profile?.last_login_at) })] })] })] }), levelData && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('levelStatus', 'Level Status'), children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between p-4 bg-neutral-800 rounded", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('currentLevel', 'CURRENT LEVEL') }), (0, jsx_runtime_1.jsx)("div", { className: `text-xl font-bold ${lvlInfo.color}`, children: lvlInfo.label }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: lvlInfo.description })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('holdings', 'HOLDINGS') }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-white font-mono", children: ["S:", levelData.holdings?.station ?? 0, " M:", levelData.holdings?.matrix ?? 0, " Se:", levelData.holdings?.sector ?? 0, " Sy:", levelData.holdings?.system ?? 0] })] })] }), levelData.next_level_requirement && ((0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: t('progress', 'PROGRESS') }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white text-sm font-mono", children: [levelData.progress_percent ?? 0, "%"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-900 rounded-full h-2", children: (0, jsx_runtime_1.jsx)("div", { className: "h-2 rounded-full bg-cyan-400 transition-all", style: { width: `${Math.min(levelData.progress_percent ?? 0, 100)}%` } }) }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-2", children: levelData.next_level_requirement.description || '' }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400 mt-1", children: [levelData.next_level_requirement.have, "/", levelData.next_level_requirement.need, ' ', levelData.next_level_requirement.tier, " \u2192 ", ' ', (0, jsx_runtime_1.jsx)("span", { className: "text-white", children: levelData.next_rank })] })] }))] }) })), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('emailVerification', 'Email Verification'), children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('status', 'STATUS') }), profile?.email_verified ? ((0, jsx_runtime_1.jsx)("div", { className: "text-green-400 text-sm", children: t('statusVerified', 'Verified') })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-red-400 text-sm", children: t('statusUnverified', 'Unverified') }))] }), !profile?.email_verified && ((0, jsx_runtime_1.jsx)("button", { onClick: async () => {
138
140
  setResendingVerification(true);
139
141
  setResendMessage(null);
140
142
  try {
141
143
  await api.post('/users/me/resend-verification', {});
142
- setResendMessage('Verification email sent — check your inbox');
144
+ setResendMessage(t('verificationSent', 'Verification email sent — check your inbox'));
143
145
  }
144
146
  catch (e) {
145
147
  setResendMessage(e instanceof Error ? e.message : 'Failed to send');
@@ -147,7 +149,7 @@ function MicrocosmProfilePage({ walletSection, } = {}) {
147
149
  finally {
148
150
  setResendingVerification(false);
149
151
  }
150
- }, disabled: resendingVerification, className: "px-3 py-1.5 border border-cyan-800 text-cyan-400 hover:bg-cyan-950 rounded text-xs disabled:opacity-50", children: resendingVerification ? 'Sending...' : 'Resend Email' }))] }), resendMessage && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400", children: resendMessage }))] }) }), (0, jsx_runtime_1.jsx)(email_change_card_1.MicrocosmEmailChangeCard, { onSuccess: (newEmail) => {
152
+ }, disabled: resendingVerification, className: "px-3 py-1.5 border border-cyan-800 text-cyan-400 hover:bg-cyan-950 rounded text-xs disabled:opacity-50", children: resendingVerification ? t('sending', 'Sending...') : t('resendEmail', 'Resend Email') }))] }), resendMessage && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400", children: resendMessage }))] }) }), (0, jsx_runtime_1.jsx)(email_change_card_1.MicrocosmEmailChangeCard, { onSuccess: (newEmail) => {
151
153
  setProfile(prev => (prev ? { ...prev, email: newEmail, email_verified: true } : prev));
152
- } }), (0, jsx_runtime_1.jsx)(two_factor_settings_1.MicrocosmTwoFactorSettings, {}), walletSection, (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-neutral-400 text-sm mb-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-cyan-400", children: "!" }), " Security"] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-1 text-sm text-neutral-400", children: [(0, jsx_runtime_1.jsx)("p", { children: "- Keep your account credentials secure" }), (0, jsx_runtime_1.jsx)("p", { children: "- Change password periodically via main portal" }), (0, jsx_runtime_1.jsx)("p", { children: "- Report suspicious activity immediately" }), (0, jsx_runtime_1.jsx)("p", { children: "- Verify your email to receive important notifications" })] })] })] }));
154
+ } }), (0, jsx_runtime_1.jsx)(two_factor_settings_1.MicrocosmTwoFactorSettings, {}), walletSection, (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-neutral-400 text-sm mb-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-cyan-400", children: "!" }), " ", t('securityTitle', 'Security')] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-1 text-sm text-neutral-400", children: [(0, jsx_runtime_1.jsxs)("p", { children: ["- ", t('securityTip1', 'Keep your account credentials secure')] }), (0, jsx_runtime_1.jsxs)("p", { children: ["- ", t('securityTip2', 'Change password periodically via main portal')] }), (0, jsx_runtime_1.jsxs)("p", { children: ["- ", t('securityTip3', 'Report suspicious activity immediately')] }), (0, jsx_runtime_1.jsxs)("p", { children: ["- ", t('securityTip4', 'Verify your email to receive important notifications')] })] })] })] }));
153
155
  }
@@ -6,7 +6,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  function MicrocosmTwoFactorSettings({} = {}) {
11
+ const t = (0, i18n_context_1.useTranslations)('profile');
10
12
  const { status, setupData, loading, error, beginSetup, verifySetup, disable, clearError, clearSetup, } = (0, auth_react_1.useTwoFactor)();
11
13
  const [step, setStep] = (0, react_1.useState)('idle');
12
14
  const [verifyCode, setVerifyCode] = (0, react_1.useState)('');
@@ -59,15 +61,15 @@ function MicrocosmTwoFactorSettings({} = {}) {
59
61
  };
60
62
  if (loading && !status)
61
63
  return null;
62
- return ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-300 font-medium tracking-wider", children: "TWO FACTOR AUTH" }) }), (0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 rounded text-xs ${status?.enabled ? 'bg-green-900/30 text-green-400 border border-green-800' : 'bg-neutral-800 text-neutral-400 border border-neutral-700'}`, children: status?.enabled ? 'enabled' : 'disabled' })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-2 bg-red-900/20 border border-red-800 rounded text-xs text-red-300 mb-3", children: error })), step === 'idle' && !status?.enabled && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Add an extra layer of security using Google Authenticator or any TOTP app." }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBegin, disabled: loading, className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs disabled:opacity-50", children: loading ? 'Setting up...' : 'Enable 2FA' })] })), step === 'idle' && status?.enabled && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 mb-1", children: "STATUS" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-green-400 text-sm", children: ["Active ", status.created_at ? `since ${new Date(status.created_at).toLocaleDateString()}` : ''] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setStep('disable'), className: "px-3 py-1.5 border border-red-900 text-red-400 hover:bg-red-950 rounded text-xs", children: "Disable 2FA" })] })), step === 'qr' && setupData && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "1. Scan this QR code with Google Authenticator or any TOTP app." }), setupData.qr_code && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center bg-white rounded p-4", children: (0, jsx_runtime_1.jsx)("img", { src: setupData.qr_code.startsWith('data:') ? setupData.qr_code : `data:image/png;base64,${setupData.qr_code}`, alt: "2FA QR Code", className: "w-48 h-48" }) })), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "MANUAL KEY" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSecret(!showSecret), className: "text-neutral-500 hover:text-neutral-300 text-xs", children: showSecret ? 'hide' : 'show' })] }), (0, jsx_runtime_1.jsx)("code", { className: "text-xs text-cyan-400 break-all", children: showSecret ? setupData.secret : '••••••••••••••••' })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "2. Enter the 6-digit code from your app." }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", value: verifyCode, onChange: (e) => setVerifyCode(e.target.value.replace(/\D/g, '').slice(0, 6)), placeholder: "000000", className: "flex-1 bg-neutral-800 border border-neutral-700 text-white p-2 rounded text-center text-lg font-mono tracking-[0.5em] outline-none focus:border-cyan-500", maxLength: 6 }), (0, jsx_runtime_1.jsx)("button", { onClick: handleVerify, disabled: loading || verifyCode.length !== 6, className: "px-4 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs disabled:opacity-50", children: loading ? 'Verifying...' : 'Verify' })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
64
+ return ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-300 font-medium tracking-wider", children: t('twoFactorAuth', 'TWO FACTOR AUTH') }) }), (0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 rounded text-xs ${status?.enabled ? 'bg-green-900/30 text-green-400 border border-green-800' : 'bg-neutral-800 text-neutral-400 border border-neutral-700'}`, children: status?.enabled ? t('enabled', 'enabled') : t('disabled', 'disabled') })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-2 bg-red-900/20 border border-red-800 rounded text-xs text-red-300 mb-3", children: error })), step === 'idle' && !status?.enabled && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('twoFactorDesc', 'Add an extra layer of security using Google Authenticator or any TOTP app.') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBegin, disabled: loading, className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs disabled:opacity-50", children: loading ? t('settingUp', 'Setting up...') : t('enable2fa', 'Enable 2FA') })] })), step === 'idle' && status?.enabled && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 mb-1", children: t('status', 'STATUS') }), (0, jsx_runtime_1.jsxs)("div", { className: "text-green-400 text-sm", children: [t('active', 'Active'), " ", status.created_at ? `${t('since', 'since')} ${new Date(status.created_at).toLocaleDateString()}` : ''] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setStep('disable'), className: "px-3 py-1.5 border border-red-900 text-red-400 hover:bg-red-950 rounded text-xs", children: t('disable2fa', 'Disable 2FA') })] })), step === 'qr' && setupData && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('scanQrStep', '1. Scan this QR code with Google Authenticator or any TOTP app.') }), setupData.qr_code && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center bg-white rounded p-4", children: (0, jsx_runtime_1.jsx)("img", { src: setupData.qr_code.startsWith('data:') ? setupData.qr_code : `data:image/png;base64,${setupData.qr_code}`, alt: "2FA QR Code", className: "w-48 h-48" }) })), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: t('manualKey', 'MANUAL KEY') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSecret(!showSecret), className: "text-neutral-500 hover:text-neutral-300 text-xs", children: showSecret ? t('hide', 'hide') : t('show', 'show') })] }), (0, jsx_runtime_1.jsx)("code", { className: "text-xs text-cyan-400 break-all", children: showSecret ? setupData.secret : '••••••••••••••••' })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('enter6DigitCode', '2. Enter the 6-digit code from your app.') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", value: verifyCode, onChange: (e) => setVerifyCode(e.target.value.replace(/\D/g, '').slice(0, 6)), placeholder: "000000", className: "flex-1 bg-neutral-800 border border-neutral-700 text-white p-2 rounded text-center text-lg font-mono tracking-[0.5em] outline-none focus:border-cyan-500", maxLength: 6 }), (0, jsx_runtime_1.jsx)("button", { onClick: handleVerify, disabled: loading || verifyCode.length !== 6, className: "px-4 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs disabled:opacity-50", children: loading ? t('verifying', 'Verifying...') : t('verify', 'Verify') })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
63
65
  setStep('idle');
64
66
  setVerifyCode('');
65
67
  clearSetup();
66
- }, className: "w-full py-2 text-neutral-500 hover:text-neutral-300 text-xs", children: "Cancel" })] })), step === 'backup' && backupCodes && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-yellow-950/30 border border-yellow-900/50 rounded p-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-yellow-400 font-medium mb-1", children: "Save your backup codes" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-yellow-600", children: "These codes can be used to access your account if you lose your authenticator. Each code can only be used once. Store them safely." })] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card font-mono text-sm space-y-1", children: backupCodes.map((code, i) => ((0, jsx_runtime_1.jsx)("div", { className: "text-cyan-400", children: code }, i))) }), (0, jsx_runtime_1.jsx)("button", { onClick: copyBackupCodes, className: "w-full px-3 py-2 border border-neutral-700 text-neutral-300 hover:bg-neutral-800 rounded text-xs", children: "Copy codes" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
68
+ }, className: "w-full py-2 text-neutral-500 hover:text-neutral-300 text-xs", children: t('cancel', 'Cancel') })] })), step === 'backup' && backupCodes && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-yellow-950/30 border border-yellow-900/50 rounded p-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-yellow-400 font-medium mb-1", children: t('saveBackupCodes', 'Save your backup codes') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-yellow-600", children: t('backupCodesDesc', 'These codes can be used to access your account if you lose your authenticator. Each code can only be used once. Store them safely.') })] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-4 blockchain-sub-card font-mono text-sm space-y-1", children: backupCodes.map((code, i) => ((0, jsx_runtime_1.jsx)("div", { className: "text-cyan-400", children: code }, i))) }), (0, jsx_runtime_1.jsx)("button", { onClick: copyBackupCodes, className: "w-full px-3 py-2 border border-neutral-700 text-neutral-300 hover:bg-neutral-800 rounded text-xs", children: t('copyCodes', 'Copy codes') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
67
69
  setStep('idle');
68
70
  setBackupCodes(null);
69
- }, className: "w-full px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs", children: "Done" })] })), step === 'disable' && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Enter your password to disable two-factor authentication." }), (0, jsx_runtime_1.jsx)("input", { type: "password", value: disablePassword, onChange: (e) => setDisablePassword(e.target.value), placeholder: "Current password", className: "w-full bg-neutral-800 border border-neutral-700 text-white p-2 rounded text-sm outline-none focus:border-cyan-500" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
71
+ }, className: "w-full px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-xs", children: t('done', 'Done') })] })), step === 'disable' && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('enterPasswordToDisable', 'Enter your password to disable two-factor authentication.') }), (0, jsx_runtime_1.jsx)("input", { type: "password", value: disablePassword, onChange: (e) => setDisablePassword(e.target.value), placeholder: t('currentPasswordPlaceholder', 'Current password'), className: "w-full bg-neutral-800 border border-neutral-700 text-white p-2 rounded text-sm outline-none focus:border-cyan-500" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
70
72
  setStep('idle');
71
73
  setDisablePassword('');
72
- }, className: "flex-1 px-3 py-1.5 text-neutral-500 hover:text-neutral-300 text-xs", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleDisable, disabled: loading || !disablePassword, className: "flex-1 px-3 py-1.5 bg-red-900 hover:bg-red-800 text-white rounded text-xs disabled:opacity-50", children: loading ? 'Disabling...' : 'Disable 2FA' })] })] }))] }));
74
+ }, className: "flex-1 px-3 py-1.5 text-neutral-500 hover:text-neutral-300 text-xs", children: t('cancel', 'Cancel') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleDisable, disabled: loading || !disablePassword, className: "flex-1 px-3 py-1.5 bg-red-900 hover:bg-red-800 text-white rounded text-xs disabled:opacity-50", children: loading ? t('disabling', 'Disabling...') : t('disable2fa', 'Disable 2FA') })] })] }))] }));
73
75
  }
@@ -6,6 +6,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  const LEVEL_LABELS = {
10
11
  miner: 'Miner',
11
12
  commander: 'Commander',
@@ -14,6 +15,7 @@ const LEVEL_LABELS = {
14
15
  admiral: 'Admiral',
15
16
  };
16
17
  function MicrocosmQueueStatusPage({ isAdmin = false } = {}) {
18
+ const t = (0, i18n_context_1.useTranslations)('queueStatus');
17
19
  const api = (0, auth_react_1.useMicrocosmApi)();
18
20
  const [userQueue, setUserQueue] = (0, react_1.useState)(null);
19
21
  const [adminQueue, setAdminQueue] = (0, react_1.useState)(null);
@@ -105,9 +107,9 @@ function MicrocosmQueueStatusPage({ isAdmin = false } = {}) {
105
107
  }
106
108
  };
107
109
  if (loading) {
108
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Station Queue" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "Your onboarding status" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Loading..." }) })] }));
110
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Territory Position Management') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'Onboarding, queuing, and territory assignment management') })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: t('loading', 'Loading...') }) })] }));
109
111
  }
110
112
  const level = userQueue?.user_type?.toLowerCase() || 'miner';
111
113
  const levelLabel = LEVEL_LABELS[level] || 'Miner';
112
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Station Queue" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "Your onboarding status" })] }), (0, jsx_runtime_1.jsx)("button", { onClick: loadStatus, className: "px-3 py-1.5 text-xs border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded transition-colors", children: "Refresh" })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "p-4 bg-neutral-800 rounded mb-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase", children: "CURRENT LEVEL" }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-cyan-300", children: levelLabel })] }), (0, jsx_runtime_1.jsxs)("span", { className: "px-3 py-1 bg-cyan-900/30 text-cyan-300 rounded border border-cyan-700 text-xs", children: ["Lv.", Object.keys(LEVEL_LABELS).indexOf(level) + 3] })] }) }), userQueue?.is_onboarded ? ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: "Onboarded" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-sm text-neutral-400", children: ["Assigned to ", userQueue.station_name || userQueue.territory_id || ''] })] }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 bg-white/20 text-white rounded text-xs", children: "Active" })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 gap-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 rounded-lg p-4 text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xl font-bold text-white", children: userQueue.territory_id }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "Territory ID" })] }) })] })) : userQueue?.in_queue ? ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-800", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: "In Queue" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "Waiting for station assignment" })] }), userQueue.status && ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 bg-cyan-900/30 text-cyan-300 rounded text-xs", children: userQueue.status }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: userQueue.position || '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Position" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: userQueue.estimated_wait_minutes || '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Est. wait (min)" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-white truncate", children: userQueue.preferred_territory_id || 'Auto' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Preferred" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-white", children: userQueue.joined_at ? new Date(userQueue.joined_at).toLocaleString() : '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: "Joined at" })] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowCancelConfirm(true), disabled: submitting, className: "w-full py-2 bg-neutral-800 hover:bg-neutral-700 text-white rounded transition-colors disabled:opacity-50", children: "Cancel Queue" })] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-800", children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: "Not Onboarded" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "Join the queue to be assigned a station" })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowJoinConfirm(true), disabled: submitting, className: "w-full py-2 bg-white/20 hover:bg-neutral-800 text-white border border-neutral-700 rounded transition-colors disabled:opacity-50", children: "Join Queue" })] }))] }), isAdmin && adminQueue && ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { title: "Queue Management (Admin)", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.pending_count ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: "Pending" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.processing_count ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: "Processing" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.total_in_queue ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: "Total in queue" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm text-white", children: adminQueue.oldest_pending ? new Date(adminQueue.oldest_pending).toLocaleString() : '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: "Oldest pending" })] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: handleProcessQueue, disabled: submitting, className: "w-full px-4 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? 'Processing...' : 'Process Queue (batch 50)' })] })), isAdmin && expansion && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Station Expansion (Admin)", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-neutral-300", children: ["Needs expansion: ", expansion.needs_expansion ? 'YES' : 'NO'] }), expansion.reason && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500 mt-1", children: ["Reason: ", expansion.reason] }))] }), (0, jsx_runtime_1.jsx)("button", { onClick: handleTriggerExpansion, disabled: submitting || !expansion.needs_expansion, className: "px-4 py-2 bg-red-900/30 text-red-300 border border-red-800 hover:bg-red-900/50 rounded text-sm disabled:opacity-50", children: submitting ? 'Expanding...' : 'Trigger Expansion' })] }) })), showJoinConfirm && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowJoinConfirm(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: "Confirm Join Queue" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "You will be added to the station queue. Auto-assignment happens when a slot opens." }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowJoinConfirm(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleJoin, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? 'Joining...' : 'Confirm' })] })] }) })), showCancelConfirm && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowCancelConfirm(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: "Cancel Queue" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "Are you sure? You will lose your current queue position." }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowCancelConfirm(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Keep Waiting" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleCancel, disabled: submitting, className: "flex-1 px-3 py-2 bg-red-700 hover:bg-red-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? 'Cancelling...' : 'Confirm Cancel' })] })] }) }))] }));
114
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Territory Position Management') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'Onboarding, queuing, and territory assignment management') })] }), (0, jsx_runtime_1.jsx)("button", { onClick: loadStatus, className: "px-3 py-1.5 text-xs border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded transition-colors", children: t('refresh', 'Refresh') })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "p-4 bg-neutral-800 rounded mb-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase", children: t('currentLevel', 'CURRENT LEVEL') }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-cyan-300", children: levelLabel })] }), (0, jsx_runtime_1.jsxs)("span", { className: "px-3 py-1 bg-cyan-900/30 text-cyan-300 rounded border border-cyan-700 text-xs", children: ["Lv.", Object.keys(LEVEL_LABELS).indexOf(level) + 3] })] }) }), userQueue?.is_onboarded ? ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: t('onboarded', 'Onboarded') }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('onboardedTo', 'You have been onboarded to {station}', { station: userQueue.station_name || userQueue.territory_id || '' }) })] }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 bg-white/20 text-white rounded text-xs", children: t('active', 'Active') })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 gap-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 rounded-lg p-4 text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xl font-bold text-white", children: userQueue.territory_id }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('territoryId', 'Territory ID') })] }) })] })) : userQueue?.in_queue ? ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-800", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: t('inQueue', 'In Queue') }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('waitingAssignment', 'You are waiting for territory assignment') })] }), userQueue.status && ((0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 bg-cyan-900/30 text-cyan-300 rounded text-xs", children: userQueue.status }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: userQueue.position || '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('queuePosition', 'Queue Position') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: userQueue.estimated_wait_minutes || '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('estimatedWait', 'Est. Wait (min)') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-white truncate", children: userQueue.preferred_territory_id || t('autoAssign', 'Auto Assign') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('preferredTerritory', 'Preferred Territory') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-white", children: userQueue.joined_at ? new Date(userQueue.joined_at).toLocaleString() : '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400", children: t('joinTime', 'Join Time') })] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowCancelConfirm(true), disabled: submitting, className: "w-full py-2 bg-neutral-800 hover:bg-neutral-700 text-white rounded transition-colors disabled:opacity-50", children: t('cancelQueue', 'Cancel Queue') })] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded-lg p-6 border border-neutral-800", children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-semibold text-white", children: t('notOnboarded', 'Not Onboarded') }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('notOnboardedDesc', 'You have not been onboarded to any territory') })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowJoinConfirm(true), disabled: submitting, className: "w-full py-2 bg-white/20 hover:bg-neutral-800 text-white border border-neutral-700 rounded transition-colors disabled:opacity-50", children: t('joinQueue', 'Join Queue') })] }))] }), isAdmin && adminQueue && ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { title: t('queueManagement', 'Queue Management (Admin)'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.pending_count ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: t('pending', 'Pending') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.processing_count ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: t('processing', 'Processing') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-white", children: adminQueue.total_in_queue ?? 0 }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: t('totalInQueue', 'Total in Queue') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-950 rounded p-4 text-center border border-neutral-800", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm text-white", children: adminQueue.oldest_pending ? new Date(adminQueue.oldest_pending).toLocaleString() : '-' }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-400 mt-1", children: t('oldestPending', 'Oldest Pending') })] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: handleProcessQueue, disabled: submitting, className: "w-full px-4 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? t('submitting', 'Processing...') : t('processQueue', 'Process Queue') })] })), isAdmin && expansion && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('territoryExpansion', 'Territory Expansion (Admin)'), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-neutral-300", children: [t('needsExpansion', 'Needs Expansion'), ": ", expansion.needs_expansion ? 'YES' : 'NO'] }), expansion.reason && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500 mt-1", children: ["Reason: ", expansion.reason] }))] }), (0, jsx_runtime_1.jsx)("button", { onClick: handleTriggerExpansion, disabled: submitting || !expansion.needs_expansion, className: "px-4 py-2 bg-red-900/30 text-red-300 border border-red-800 hover:bg-red-900/50 rounded text-sm disabled:opacity-50", children: submitting ? t('submitting', 'Processing...') : t('triggerExpansion', 'Trigger Expansion Manually') })] }) })), showJoinConfirm && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowJoinConfirm(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: t('joinDialogTitle', 'Join Territory') }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('joinDialogDesc', 'Choose to join a specific territory or auto-assign') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowJoinConfirm(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('cancel', 'Cancel') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleJoin, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? t('submitting', 'Processing...') : t('immediateJoin', 'Join Immediately') })] })] }) })), showCancelConfirm && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowCancelConfirm(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: t('cancelQueueTitle', 'Cancel Queue') }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: t('cancelQueueDesc', 'Are you sure you want to cancel queuing? You will need to rejoin the queue to get onboarded.') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowCancelConfirm(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('goBack', 'Go Back') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleCancel, disabled: submitting, className: "flex-1 px-3 py-2 bg-red-700 hover:bg-red-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? t('submitting', 'Processing...') : t('confirmCancel', 'Confirm Cancel') })] })] }) }))] }));
113
115
  }
@@ -6,6 +6,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  const POOL_ADDRESS = 'REDEh89TzpwCtoWQuuNPtxskrVoUDQgowR7e7sZpWj9';
10
11
  const USDT_VAULT = 'BnHA9jSm88wzQS4c2nCgTXch1Byzc3FWn2G7Wgrvazy3';
11
12
  const USDC_VAULT = '5L8vPTvGH14keLq4R6CGGvSFksZFjb7bRPXarCwZbmUA';
@@ -26,8 +27,11 @@ function formatNumber(num, decimals = 2) {
26
27
  return (num / 1000000).toFixed(2) + 'M';
27
28
  return num.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
28
29
  }
29
- function MicrocosmReincarnationPage({ title = 'Reincarnation Pool', subtitle = '2140 Protocol autonomous market making', } = {}) {
30
+ function MicrocosmReincarnationPage({ title, subtitle, } = {}) {
31
+ const t = (0, i18n_context_1.useTranslations)('reincarnationDash');
32
+ const resolvedTitle = title ?? t('title', 'Reincarnation Pool');
33
+ const resolvedSubtitle = subtitle ?? t('subtitle', '2140 Protocol autonomous market making');
30
34
  const { data: priceData, loading } = (0, auth_react_1.useMCCPrice)({ refetchInterval: 60000 });
31
35
  const basePrice = priceData?.price ?? 0;
32
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: title }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400 mt-1", children: subtitle })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "BASE PRICE" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-2xl font-bold text-cyan-400", children: [loading ? '—' : formatNumber(basePrice, 4), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-normal text-neutral-500 ml-1", children: "USD" })] })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "PROTOCOL" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: "2140" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "EMA weighted" })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "EPOCH" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: "1h" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "Auto buyback" })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "DEX" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: "Raydium" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "CPMM pool" })] })] }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Contract Addresses", children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Reincarnation Pool PDA" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-sm text-cyan-400 break-all", children: POOL_ADDRESS }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [(0, jsx_runtime_1.jsx)(CopyButton, { text: POOL_ADDRESS }), (0, jsx_runtime_1.jsx)("a", { href: `https://solscan.io/account/${POOL_ADDRESS}`, target: "_blank", rel: "noopener noreferrer", className: "text-neutral-400 hover:text-white text-xs", children: "\u2197" })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "USDT Vault" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-xs text-neutral-400 break-all", children: USDT_VAULT }), (0, jsx_runtime_1.jsx)(CopyButton, { text: USDT_VAULT })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "USDC Vault" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-xs text-neutral-400 break-all", children: USDC_VAULT }), (0, jsx_runtime_1.jsx)(CopyButton, { text: USDC_VAULT })] })] })] })] }) }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Mechanism", children: (0, jsx_runtime_1.jsxs)("div", { className: "text-sm space-y-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-medium text-cyan-400 tracking-wider", children: "Autonomous Market Making" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 leading-relaxed", children: "The Reincarnation Pool is a Solana PDA-owned autonomous market maker. Every epoch (1 hour), it reads the CPMM spot price, updates an EMA-weighted oracle (weight 2140), and executes a permissionless buyback via CPMM swap. Proceeds flow to the Mining Vault for the next cycle of community mining." }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center gap-2 mt-3 text-xs", children: [(0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-white/10 text-white", children: "Raydium CPMM" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "PDA Autonomous" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "EMA Oracle" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "Permissionless" })] })] }) })] }));
36
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: resolvedTitle }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400 mt-1", children: resolvedSubtitle })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "BASE PRICE" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-2xl font-bold text-cyan-400", children: [loading ? '—' : formatNumber(basePrice, 4), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-normal text-neutral-500 ml-1", children: "USD" })] })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "PROTOCOL" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: "2140" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "EMA weighted" })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "EPOCH" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: "1h" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "Auto buyback" })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-2", children: "DEX" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: "Raydium" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500 mt-1", children: "CPMM pool" })] })] }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('contractAddresses', 'Contract Addresses'), children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Reincarnation Pool PDA" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-sm text-cyan-400 break-all", children: POOL_ADDRESS }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [(0, jsx_runtime_1.jsx)(CopyButton, { text: POOL_ADDRESS }), (0, jsx_runtime_1.jsx)("a", { href: `https://solscan.io/account/${POOL_ADDRESS}`, target: "_blank", rel: "noopener noreferrer", className: "text-neutral-400 hover:text-white text-xs", children: "\u2197" })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('usdtBalance', 'USDT Vault') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-xs text-neutral-400 break-all", children: USDT_VAULT }), (0, jsx_runtime_1.jsx)(CopyButton, { text: USDT_VAULT })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-white/5 border border-white/10 rounded-lg p-3 blockchain-sub-card", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: t('usdcBalance', 'USDC Vault') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsx)("code", { className: "text-xs text-neutral-400 break-all", children: USDC_VAULT }), (0, jsx_runtime_1.jsx)(CopyButton, { text: USDC_VAULT })] })] })] })] }) }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('mechanism', 'Market Making Mechanism'), children: (0, jsx_runtime_1.jsxs)("div", { className: "text-sm space-y-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-medium text-cyan-400 tracking-wider", children: t('mechanism', 'Market Making Mechanism') }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 leading-relaxed", children: t('mechanismDesc', 'The Reincarnation Pool is a Solana PDA-owned autonomous market maker. Every epoch (1 hour), it reads the CPMM spot price, updates an EMA-weighted oracle (weight 2140), and executes a permissionless buyback via CPMM swap. Proceeds flow to the Mining Vault for the next cycle of community mining.') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center gap-2 mt-3 text-xs", children: [(0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-white/10 text-white", children: "Raydium CPMM" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "PDA Autonomous" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "EMA Oracle" }), (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 rounded bg-cyan-400/20 text-cyan-400", children: "Permissionless" })] })] }) })] }));
33
37
  }
@@ -6,7 +6,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  function MicrocosmRewardsPage({} = {}) {
11
+ const t = (0, i18n_context_1.useTranslations)('rewardsDash');
10
12
  const api = (0, auth_react_1.useMicrocosmApi)();
11
13
  const [history, setHistory] = (0, react_1.useState)([]);
12
14
  const [stats, setStats] = (0, react_1.useState)(null);
@@ -105,11 +107,11 @@ function MicrocosmRewardsPage({} = {}) {
105
107
  return '-';
106
108
  }
107
109
  };
108
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Rewards" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "Send MCC rewards to your territory members" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSendDialog(true), className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm", children: "Send Reward" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowBatchDialog(true), className: "px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded text-sm", children: "Batch Send" })] })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), stats && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "MCC RECEIVED" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: Number(stats.total_received || 0).toFixed(2) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "MCC SENT" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: Number(stats.total_sent || 0).toFixed(2) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "RECEIVE COUNT" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: stats.receive_count })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "SEND COUNT" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: stats.send_count })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setTab('history'), className: `px-4 py-2 text-sm ${tab === 'history' ? 'text-white border-b-2 border-cyan-400' : 'text-neutral-400 hover:text-white'}`, children: "History" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setTab('leaderboard'), className: `px-4 py-2 text-sm ${tab === 'leaderboard' ? 'text-white border-b-2 border-cyan-400' : 'text-neutral-400 hover:text-white'}`, children: "Leaderboard" })] }), tab === 'history' && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Reward History", children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: "Loading..." })) : history.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: "No records" })) : ((0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { className: "text-xs text-neutral-400 border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: "Time" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: "Sender" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: "Recipient" }), (0, jsx_runtime_1.jsx)("th", { className: "text-right py-2", children: "Amount" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: "Reason" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: history.map(record => ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("td", { className: "py-2 text-xs text-neutral-500", children: formatDate(record.created_at) }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-neutral-300", children: record.manager_email || record.manager_id }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-neutral-300", children: record.recipient_email || record.recipient_id }), (0, jsx_runtime_1.jsxs)("td", { className: "py-2 text-right text-white", children: ["+", Number(record.amount || 0).toFixed(2), " MCC"] }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-xs text-neutral-500", children: record.reason || '-' })] }, record.id))) })] }) })) })), tab === 'leaderboard' && ((0, jsx_runtime_1.jsxs)("div", { className: "grid md:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Top Recipients", children: topRecipients.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500", children: "No data" })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: topRecipients.map((entry, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: `w-6 h-6 flex items-center justify-center rounded text-xs ${idx < 3 ? 'bg-cyan-400/20 text-cyan-300' : 'bg-neutral-800 text-neutral-400'}`, children: idx + 1 }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300", children: entry.email || entry.user_id })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white", children: [Number(entry.total_received || 0).toFixed(2), " MCC"] })] }, entry.user_id))) })) }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: "Top Senders", children: topSenders.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500", children: "No data" })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: topSenders.map((entry, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: `w-6 h-6 flex items-center justify-center rounded text-xs ${idx < 3 ? 'bg-cyan-400/20 text-cyan-300' : 'bg-neutral-800 text-neutral-400'}`, children: idx + 1 }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300", children: entry.email || entry.user_id })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-cyan-400", children: [Number(entry.total_sent || 0).toFixed(2), " MCC"] })] }, entry.user_id))) })) })] })), showSendDialog && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowSendDialog(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: "Send Single Reward" }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Recipient UID" }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: singleReward.recipient_id, onChange: (e) => setSingleReward({ ...singleReward, recipient_id: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm", placeholder: "uid" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Amount (MCC)" }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: 1, max: 10000, value: singleReward.amount, onChange: (e) => setSingleReward({ ...singleReward, amount: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm", placeholder: "1-10000" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Reason" }), (0, jsx_runtime_1.jsx)("textarea", { value: singleReward.reason, onChange: (e) => setSingleReward({ ...singleReward, reason: e.target.value }), rows: 2, className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSendDialog(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleSendReward, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? 'Sending...' : 'Send' })] })] }) })), showBatchDialog && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowBatchDialog(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-2xl p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: "Batch Reward Send" }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2 max-h-96 overflow-y-auto", children: [batchRewards.map((r, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 items-start", children: [(0, jsx_runtime_1.jsx)("input", { value: r.user_id, onChange: (e) => {
110
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Manager Rewards') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'Reward team members with your personal MCC') })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSendDialog(true), className: "px-3 py-1.5 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm", children: t('sendReward', 'Send Reward') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowBatchDialog(true), className: "px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded text-sm", children: t('batchSend', 'Batch Send') })] })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), stats && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: t('mccReceived', 'MCC Received') }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: Number(stats.total_received || 0).toFixed(2) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: t('mccSent', 'MCC Sent') }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: Number(stats.total_sent || 0).toFixed(2) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: t('receiveCount', 'Times Received') }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: stats.receive_count })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: t('sendCount', 'Times Sent') }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: stats.send_count })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setTab('history'), className: `px-4 py-2 text-sm ${tab === 'history' ? 'text-white border-b-2 border-cyan-400' : 'text-neutral-400 hover:text-white'}`, children: t('historyTab', 'History') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setTab('leaderboard'), className: `px-4 py-2 text-sm ${tab === 'leaderboard' ? 'text-white border-b-2 border-cyan-400' : 'text-neutral-400 hover:text-white'}`, children: t('leaderboardTab', 'Leaderboard') })] }), tab === 'history' && ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('rewardHistory', 'Reward History'), children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: t('loadingText', 'Loading...') })) : history.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: t('noRecords', 'No reward records') })) : ((0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { className: "text-xs text-neutral-400 border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: t('time', 'Time') }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: t('sender', 'Sender') }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: t('recipient', 'Recipient') }), (0, jsx_runtime_1.jsx)("th", { className: "text-right py-2", children: t('amount', 'Amount') }), (0, jsx_runtime_1.jsx)("th", { className: "text-left py-2", children: t('reason', 'Reason') })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: history.map(record => ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("td", { className: "py-2 text-xs text-neutral-500", children: formatDate(record.created_at) }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-neutral-300", children: record.manager_email || record.manager_id }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-neutral-300", children: record.recipient_email || record.recipient_id }), (0, jsx_runtime_1.jsxs)("td", { className: "py-2 text-right text-white", children: ["+", Number(record.amount || 0).toFixed(2), " MCC"] }), (0, jsx_runtime_1.jsx)("td", { className: "py-2 text-xs text-neutral-500", children: record.reason || '-' })] }, record.id))) })] }) })) })), tab === 'leaderboard' && ((0, jsx_runtime_1.jsxs)("div", { className: "grid md:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('topReceived', 'Most Received This Month'), children: topRecipients.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500", children: t('noData', 'No data') })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: topRecipients.map((entry, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: `w-6 h-6 flex items-center justify-center rounded text-xs ${idx < 3 ? 'bg-cyan-400/20 text-cyan-300' : 'bg-neutral-800 text-neutral-400'}`, children: idx + 1 }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300", children: entry.email || entry.user_id })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white", children: [Number(entry.total_received || 0).toFixed(2), " MCC"] })] }, entry.user_id))) })) }), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { title: t('topSent', 'Most Sent This Month'), children: topSenders.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500", children: t('noData', 'No data') })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: topSenders.map((entry, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: `w-6 h-6 flex items-center justify-center rounded text-xs ${idx < 3 ? 'bg-cyan-400/20 text-cyan-300' : 'bg-neutral-800 text-neutral-400'}`, children: idx + 1 }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300", children: entry.email || entry.user_id })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-cyan-400", children: [Number(entry.total_sent || 0).toFixed(2), " MCC"] })] }, entry.user_id))) })) })] })), showSendDialog && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowSendDialog(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-md p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: t('sendSingleTitle', 'Send Single Reward') }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('recipientId', 'Recipient ID') }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: singleReward.recipient_id, onChange: (e) => setSingleReward({ ...singleReward, recipient_id: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm", placeholder: t('recipientPlaceholder', 'Enter user ID or email') })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('rewardAmount', 'Reward Amount (MCC)') }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: 1, max: 10000, value: singleReward.amount, onChange: (e) => setSingleReward({ ...singleReward, amount: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm", placeholder: t('amountPlaceholder', 'Enter MCC amount') })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('reasonLabel', 'Reason (optional)') }), (0, jsx_runtime_1.jsx)("textarea", { value: singleReward.reason, onChange: (e) => setSingleReward({ ...singleReward, reason: e.target.value }), rows: 2, className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowSendDialog(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('cancel', 'Cancel') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleSendReward, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? t('loadingText', 'Loading...') : t('send', 'Send') })] })] }) })), showBatchDialog && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setShowBatchDialog(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-2xl p-6 space-y-4", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-medium", children: t('batchTitle', 'Batch Send Rewards') }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2 max-h-96 overflow-y-auto", children: [batchRewards.map((r, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 items-start", children: [(0, jsx_runtime_1.jsx)("input", { value: r.user_id, onChange: (e) => {
109
111
  const next = [...batchRewards];
110
112
  next[i] = { ...next[i], user_id: e.target.value };
111
113
  setBatchRewards(next);
112
- }, placeholder: "User UID", className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-2 py-1.5 text-sm" }), (0, jsx_runtime_1.jsx)("input", { type: "number", value: r.amount, onChange: (e) => {
114
+ }, placeholder: t('userId', 'User ID'), className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-2 py-1.5 text-sm" }), (0, jsx_runtime_1.jsx)("input", { type: "number", value: r.amount, onChange: (e) => {
113
115
  const next = [...batchRewards];
114
116
  next[i] = { ...next[i], amount: e.target.value };
115
117
  setBatchRewards(next);
@@ -117,5 +119,5 @@ function MicrocosmRewardsPage({} = {}) {
117
119
  const next = [...batchRewards];
118
120
  next[i] = { ...next[i], reason: e.target.value };
119
121
  setBatchRewards(next);
120
- }, placeholder: "reason", className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-2 py-1.5 text-sm" }), batchRewards.length > 1 && ((0, jsx_runtime_1.jsx)("button", { onClick: () => setBatchRewards(batchRewards.filter((_, idx) => idx !== i)), className: "px-2 py-1 text-red-400 hover:bg-red-900/20 rounded text-sm", children: "\u00D7" }))] }, i))), (0, jsx_runtime_1.jsx)("button", { onClick: () => setBatchRewards([...batchRewards, { user_id: '', amount: '', reason: '' }]), className: "w-full px-3 py-2 border border-dashed border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "+ Add row" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowBatchDialog(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBatchReward, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? 'Sending...' : 'Batch Send' })] })] }) }))] }));
122
+ }, placeholder: t('reason', 'Reason'), className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-2 py-1.5 text-sm" }), batchRewards.length > 1 && ((0, jsx_runtime_1.jsx)("button", { onClick: () => setBatchRewards(batchRewards.filter((_, idx) => idx !== i)), className: "px-2 py-1 text-red-400 hover:bg-red-900/20 rounded text-sm", children: "\u00D7" }))] }, i))), (0, jsx_runtime_1.jsxs)("button", { onClick: () => setBatchRewards([...batchRewards, { user_id: '', amount: '', reason: '' }]), className: "w-full px-3 py-2 border border-dashed border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: ["+ ", t('addRow', 'Add Row')] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setShowBatchDialog(false), className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('cancel', 'Cancel') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBatchReward, disabled: submitting, className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: submitting ? t('loadingText', 'Loading...') : t('batchSend', 'Batch Send') })] })] }) }))] }));
121
123
  }
@@ -6,6 +6,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
7
  const auth_react_1 = require("@microcosmmoney/auth-react");
8
8
  const terminal_1 = require("../terminal");
9
+ const i18n_context_1 = require("../../i18n-context");
9
10
  const API_BASE = 'https://api.microcosm.money/v1';
10
11
  const cropToSquare = (file, size) => {
11
12
  return new Promise((resolve, reject) => {
@@ -38,6 +39,7 @@ const cropToSquare = (file, size) => {
38
39
  const UNIT_LABELS = { station: 'Station', matrix: 'Matrix', sector: 'Sector', system: 'System' };
39
40
  const MAGISTRATE_TITLES = { station: 'Commander', matrix: 'Pioneer', sector: 'Warden', system: 'Admiral' };
40
41
  function MicrocosmStationListPage({ currentUid, isAdmin = false } = {}) {
42
+ const t = (0, i18n_context_1.useTranslations)('stationList');
41
43
  const api = (0, auth_react_1.useMicrocosmApi)();
42
44
  const { getAccessToken } = (0, auth_react_1.useMicrocosmContext)();
43
45
  const [units, setUnits] = (0, react_1.useState)([]);
@@ -117,11 +119,11 @@ function MicrocosmStationListPage({ currentUid, isAdmin = false } = {}) {
117
119
  if (!file)
118
120
  return;
119
121
  if (!file.type.startsWith('image/')) {
120
- setError('Please select an image file');
122
+ setError(t('selectImageFile', 'Please select an image file'));
121
123
  return;
122
124
  }
123
125
  if (file.size > 2 * 1024 * 1024) {
124
- setError('Image must be under 2MB');
126
+ setError(t('imageTooLarge', 'Image must not exceed 2MB'));
125
127
  return;
126
128
  }
127
129
  cropToSquare(file, 512)
@@ -131,7 +133,7 @@ function MicrocosmStationListPage({ currentUid, isAdmin = false } = {}) {
131
133
  reader.onload = (ev) => setImagePreview(ev.target?.result);
132
134
  reader.readAsDataURL(cropped);
133
135
  })
134
- .catch(() => setError('Image processing failed'));
136
+ .catch(() => setError(t('imageProcessError', 'Image processing failed')));
135
137
  };
136
138
  const uploadImage = async (unitId) => {
137
139
  if (!imageFile)
@@ -203,16 +205,16 @@ function MicrocosmStationListPage({ currentUid, isAdmin = false } = {}) {
203
205
  setSubmitting(false);
204
206
  }
205
207
  };
206
- return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: "Station List" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: "All territories (Station / Matrix / Sector / System)" })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), summary && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "TOTAL STATIONS" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: summary.total_stations ?? 0 })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "TOTAL MEMBERS" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: summary.total_members ?? 0 })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "VAULT MCD" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: (summary.total_vault_mcd ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 }) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "AVG KPI" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: (summary.avg_kpi_score ?? 0).toFixed(1) })] })] })), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col md:flex-row gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 flex-wrap", children: ['all', 'station', 'matrix', 'sector', 'system'].map(f => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setFilter(f), className: `px-3 py-1.5 text-sm rounded transition-colors ${filter === f ? 'bg-cyan-700 text-white' : 'bg-neutral-800 text-neutral-400 hover:bg-neutral-700 hover:text-white'}`, children: f === 'all' ? 'All' : UNIT_LABELS[f] }, f))) }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), placeholder: "Search by name / location / short_id...", className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-1.5 text-sm focus:outline-none focus:border-cyan-400" })] }) }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Loading units..." }) })) : filteredUnits.length === 0 ? ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { children: (0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: "No units match your filter" }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: filteredUnits.map(unit => {
208
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto px-3 py-4 space-y-3 xs:px-4 xs:space-y-4 sm:px-6 sm:py-6 sm:space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-lg sm:text-2xl font-bold text-white tracking-wider", children: t('title', 'Territory Management') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs sm:text-sm text-neutral-400", children: t('subtitle', 'Manage territories, view KPI and vault balances') })] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-900/20 border border-red-800 rounded text-sm text-red-300", children: error })), summary && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "TOTAL STATIONS" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: summary.total_stations ?? 0 })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "TOTAL MEMBERS" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: summary.total_members ?? 0 })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "VAULT MCD" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400", children: (summary.total_vault_mcd ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 }) })] }), (0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase mb-1", children: "AVG KPI" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white", children: (summary.avg_kpi_score ?? 0).toFixed(1) })] })] })), (0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col md:flex-row gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 flex-wrap", children: ['all', 'station', 'matrix', 'sector', 'system'].map(f => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setFilter(f), className: `px-3 py-1.5 text-sm rounded transition-colors ${filter === f ? 'bg-cyan-700 text-white' : 'bg-neutral-800 text-neutral-400 hover:bg-neutral-700 hover:text-white'}`, children: f === 'all' ? t('all', 'All') : t(`unitTypeLabels.${f}`, UNIT_LABELS[f]) }, f))) }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), placeholder: t('searchPlaceholder', 'Search territory name, path, location...'), className: "flex-1 bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-1.5 text-sm focus:outline-none focus:border-cyan-400" })] }) }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-20", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: t('loading', 'Loading units...') }) })) : filteredUnits.length === 0 ? ((0, jsx_runtime_1.jsx)(terminal_1.TerminalCard, { children: (0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500", children: t('noTerritories', 'no territories found') }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: filteredUnits.map(unit => {
207
209
  const metrics = unitDataCache[unit.unit_id];
208
- return ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-semibold", children: unit.unit_name }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500", children: [UNIT_LABELS[unit.unit_type], " \u00B7 ", MAGISTRATE_TITLES[unit.unit_type]] }), unit.short_id && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs font-mono text-cyan-400 mt-1", children: unit.short_id }))] }), canEditUnit(unit) && ((0, jsx_runtime_1.jsx)("button", { onClick: () => openEditDialog(unit), className: "text-xs px-2 py-1 border border-neutral-700 text-neutral-400 hover:text-white hover:bg-neutral-800 rounded", children: "Edit" }))] }), unit.description && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 mb-3 line-clamp-2", children: unit.description })), metrics && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-2 pt-3 border-t border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Members" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-white", children: [metrics.member_count, "/", metrics.max_capacity] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Occupancy" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-cyan-400", children: [(metrics.occupancy_rate * 100).toFixed(0), "%"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "col-span-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Vault MCD" }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: (metrics.vault_mcd ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 }) })] })] })), unit.image_status === 'pending' && ((0, jsx_runtime_1.jsx)("div", { className: "mt-2 text-xs text-yellow-400", children: "Image pending review" }))] }, unit.unit_id));
209
- }) })), editingUnit && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setEditingUnit(null), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-lg p-6 space-y-4 max-h-[90vh] overflow-y-auto", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-medium", children: ["Edit ", editingUnit.unit_name] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Name" }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: editFormData.unit_name, onChange: (e) => setEditFormData({ ...editFormData, unit_name: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Description" }), (0, jsx_runtime_1.jsx)("textarea", { value: editFormData.description, onChange: (e) => setEditFormData({ ...editFormData, description: e.target.value }), rows: 4, className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: "Image" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-3", children: [(imagePreview || editingUnit.image_url) ? ((0, jsx_runtime_1.jsx)("img", { src: imagePreview || editingUnit.image_url, alt: "", className: "w-24 h-24 rounded object-cover border border-neutral-700" })) : ((0, jsx_runtime_1.jsx)("div", { className: "w-24 h-24 rounded bg-neutral-800 border border-neutral-700 flex items-center justify-center text-xs text-neutral-500", children: "No image" })), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 space-y-2", children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/jpeg,image/png,image/webp", onChange: handleFileSelect, className: "hidden" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => fileInputRef.current?.click(), disabled: uploadingImage, className: "w-full px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded text-sm", children: imageFile ? 'Change' : 'Select image' }), imageFile && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500", children: [imageFile.name, " (", (imageFile.size / 1024).toFixed(1), "KB)"] })), editingUnit.image_status && ((0, jsx_runtime_1.jsx)("div", { className: `text-xs px-2 py-0.5 rounded inline-block ${editingUnit.image_status === 'approved'
210
+ return ((0, jsx_runtime_1.jsxs)(terminal_1.TerminalCard, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-semibold", children: unit.unit_name }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500", children: [t(`unitTypeLabels.${unit.unit_type}`, UNIT_LABELS[unit.unit_type]), " \u00B7 ", MAGISTRATE_TITLES[unit.unit_type]] }), unit.short_id && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs font-mono text-cyan-400 mt-1", children: unit.short_id }))] }), canEditUnit(unit) && ((0, jsx_runtime_1.jsx)("button", { onClick: () => openEditDialog(unit), className: "text-xs px-2 py-1 border border-neutral-700 text-neutral-400 hover:text-white hover:bg-neutral-800 rounded", children: t('edit', 'Edit') }))] }), unit.description && ((0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 mb-3 line-clamp-2", children: unit.description })), metrics && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-2 pt-3 border-t border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: t('members', 'Members') }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-white", children: [metrics.member_count, "/", metrics.max_capacity] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: t('occupancy', 'Occupancy') }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-cyan-400", children: [(metrics.occupancy_rate * 100).toFixed(0), "%"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "col-span-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Vault MCD" }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-white", children: (metrics.vault_mcd ?? 0).toLocaleString(undefined, { maximumFractionDigits: 0 }) })] })] })), unit.image_status === 'pending' && ((0, jsx_runtime_1.jsx)("div", { className: "mt-2 text-xs text-yellow-400", children: t('reviewPending', 'Under review') }))] }, unit.unit_id));
211
+ }) })), editingUnit && ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", onClick: () => setEditingUnit(null), children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-lg p-6 space-y-4 max-h-[90vh] overflow-y-auto", onClick: e => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-medium", children: [t('editTerritory', 'Edit Territory'), ": ", editingUnit.unit_name] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('name', 'Name') }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: editFormData.unit_name, onChange: (e) => setEditFormData({ ...editFormData, unit_name: e.target.value }), className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('description', 'Description') }), (0, jsx_runtime_1.jsx)("textarea", { value: editFormData.description, onChange: (e) => setEditFormData({ ...editFormData, description: e.target.value }), rows: 4, className: "w-full bg-neutral-800 border border-neutral-600 text-white rounded px-3 py-2 text-sm" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-[#5EEAD4] tracking-widest uppercase block mb-1", children: t('image', 'Image') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-3", children: [(imagePreview || editingUnit.image_url) ? ((0, jsx_runtime_1.jsx)("img", { src: imagePreview || editingUnit.image_url, alt: "", className: "w-24 h-24 rounded object-cover border border-neutral-700" })) : ((0, jsx_runtime_1.jsx)("div", { className: "w-24 h-24 rounded bg-neutral-800 border border-neutral-700 flex items-center justify-center text-xs text-neutral-500", children: t('noImage', 'No image') })), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 space-y-2", children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", accept: "image/jpeg,image/png,image/webp", onChange: handleFileSelect, className: "hidden" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => fileInputRef.current?.click(), disabled: uploadingImage, className: "w-full px-3 py-1.5 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 hover:text-white rounded text-sm", children: imageFile ? t('change', 'Change') : t('clickToUpload', 'Click to upload') }), imageFile && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500", children: [imageFile.name, " (", (imageFile.size / 1024).toFixed(1), "KB)"] })), editingUnit.image_status && ((0, jsx_runtime_1.jsx)("div", { className: `text-xs px-2 py-0.5 rounded inline-block ${editingUnit.image_status === 'approved'
210
212
  ? 'bg-green-900/30 text-green-400'
211
213
  : editingUnit.image_status === 'rejected'
212
214
  ? 'bg-red-900/30 text-red-400'
213
- : 'bg-yellow-900/30 text-yellow-400'}`, children: editingUnit.image_status }))] })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-2", children: "Max 2MB. Auto-cropped to square (512\u00D7512). JPG/PNG/WebP." })] }), isAdmin && editingUnit.image_url && editingUnit.image_status === 'pending' && ((0, jsx_runtime_1.jsxs)("div", { className: "pt-3 border-t border-neutral-700 space-y-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400 tracking-wider", children: "ADMIN REVIEW" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => handleImageReview(editingUnit.unit_id, 'approved'), className: "flex-1 px-3 py-1.5 bg-green-900/30 text-green-400 hover:bg-green-900/50 border border-green-800 rounded text-sm", children: "Approve" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => handleImageReview(editingUnit.unit_id, 'rejected'), className: "flex-1 px-3 py-1.5 bg-red-900/30 text-red-400 hover:bg-red-900/50 border border-red-800 rounded text-sm", children: "Reject" })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
215
+ : 'bg-yellow-900/30 text-yellow-400'}`, children: editingUnit.image_status }))] })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-2", children: t('imageHint', 'Max 2MB. Auto-cropped to square (512×512). JPG/PNG/WebP.') })] }), isAdmin && editingUnit.image_url && editingUnit.image_status === 'pending' && ((0, jsx_runtime_1.jsxs)("div", { className: "pt-3 border-t border-neutral-700 space-y-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400 tracking-wider", children: t('adminReview', 'ADMIN REVIEW') }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => handleImageReview(editingUnit.unit_id, 'approved'), className: "flex-1 px-3 py-1.5 bg-green-900/30 text-green-400 hover:bg-green-900/50 border border-green-800 rounded text-sm", children: t('approve', 'Approve') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => handleImageReview(editingUnit.unit_id, 'rejected'), className: "flex-1 px-3 py-1.5 bg-red-900/30 text-red-400 hover:bg-red-900/50 border border-red-800 rounded text-sm", children: t('reject', 'Reject') })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => {
214
216
  setEditingUnit(null);
215
217
  setImageFile(null);
216
218
  setImagePreview(null);
217
- }, className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleEdit, disabled: submitting || uploadingImage || !editFormData.unit_name.trim(), className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: uploadingImage ? 'Uploading...' : submitting ? 'Saving...' : 'Save' })] })] }) }))] }));
219
+ }, className: "flex-1 px-3 py-2 border border-neutral-700 text-neutral-400 hover:bg-neutral-800 rounded text-sm", children: t('cancel', 'Cancel') }), (0, jsx_runtime_1.jsx)("button", { onClick: handleEdit, disabled: submitting || uploadingImage || !editFormData.unit_name.trim(), className: "flex-1 px-3 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm disabled:opacity-50", children: uploadingImage ? t('uploading', 'Uploading...') : submitting ? t('saving', 'Saving...') : t('save', 'Save') })] })] }) }))] }));
218
220
  }