@microcosmmoney/portal-react 3.1.0 → 3.2.1
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.
- package/dist/components/territory/territory-page.js +105 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/menu-config.d.ts +11 -0
- package/dist/menu-config.js +40 -0
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ exports.MicrocosmTerritoryPage = MicrocosmTerritoryPage;
|
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const react_1 = require("react");
|
|
8
8
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
9
|
+
const recharts_1 = require("recharts");
|
|
9
10
|
/* ------------------------------------------------------------------ */
|
|
10
11
|
/* Inline SVG Icons (24x24 viewBox, stroke 2, round caps) */
|
|
11
12
|
/* ------------------------------------------------------------------ */
|
|
@@ -81,20 +82,118 @@ function TerritoryCard({ unit, onClick }) {
|
|
|
81
82
|
/* ------------------------------------------------------------------ */
|
|
82
83
|
/* Detail View */
|
|
83
84
|
/* ------------------------------------------------------------------ */
|
|
85
|
+
/* ------------------------------------------------------------------ */
|
|
86
|
+
/* Income Chart (recharts LineChart) */
|
|
87
|
+
/* ------------------------------------------------------------------ */
|
|
88
|
+
function IncomeChart({ territoryId }) {
|
|
89
|
+
const { data: raw, loading } = (0, auth_react_1.useTerritoryIncome)(territoryId, '30d');
|
|
90
|
+
const uid = (0, react_1.useId)();
|
|
91
|
+
const chartData = (0, react_1.useMemo)(() => {
|
|
92
|
+
if (!raw)
|
|
93
|
+
return [];
|
|
94
|
+
// API may return { labels, datasets: { income, cumulative } } or array
|
|
95
|
+
if (Array.isArray(raw))
|
|
96
|
+
return raw;
|
|
97
|
+
if (raw.labels && raw.datasets) {
|
|
98
|
+
return raw.labels.map((label, i) => ({
|
|
99
|
+
date: label,
|
|
100
|
+
income: raw.datasets.income?.[i] ?? 0,
|
|
101
|
+
cumulative: raw.datasets.cumulative?.[i] ?? 0,
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
return raw.data ?? [];
|
|
105
|
+
}, [raw]);
|
|
106
|
+
if (loading)
|
|
107
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-6", children: (0, jsx_runtime_1.jsx)("div", { className: "h-64 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(Spinner, {}) }) });
|
|
108
|
+
if (chartData.length === 0)
|
|
109
|
+
return null;
|
|
110
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-4 flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconZap, { className: "w-4 h-4 text-cyan-400" }), "Income Trend (30D)"] }), (0, jsx_runtime_1.jsx)("div", { className: "h-64", children: (0, jsx_runtime_1.jsx)(recharts_1.ResponsiveContainer, { width: "100%", height: "100%", children: (0, jsx_runtime_1.jsxs)(recharts_1.LineChart, { data: chartData, margin: { top: 5, right: 10, left: 0, bottom: 5 }, children: [(0, jsx_runtime_1.jsx)(recharts_1.CartesianGrid, { strokeDasharray: "3 3", stroke: "#404040" }), (0, jsx_runtime_1.jsx)(recharts_1.XAxis, { dataKey: "date", tick: { fill: '#a3a3a3', fontSize: 11 }, axisLine: { stroke: '#525252' } }), (0, jsx_runtime_1.jsx)(recharts_1.YAxis, { tick: { fill: '#a3a3a3', fontSize: 11 }, axisLine: { stroke: '#525252' } }), (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { contentStyle: { backgroundColor: '#171717', border: '1px solid #404040', borderRadius: '8px' }, labelStyle: { color: '#a3a3a3' }, itemStyle: { color: '#fff' } }), (0, jsx_runtime_1.jsx)(recharts_1.Line, { type: "monotone", dataKey: "income", name: "Daily Income", stroke: "#22d3ee", strokeWidth: 2, dot: false, activeDot: { r: 4 } }), (0, jsx_runtime_1.jsx)(recharts_1.Line, { type: "monotone", dataKey: "cumulative", name: "Cumulative", stroke: "#ffffff", strokeWidth: 2, dot: false, activeDot: { r: 4 } })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-center gap-6 mt-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-3 h-0.5 bg-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Daily Income" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-3 h-0.5 bg-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Cumulative" })] })] })] }));
|
|
111
|
+
}
|
|
112
|
+
/* ------------------------------------------------------------------ */
|
|
113
|
+
/* Member Ranking */
|
|
114
|
+
/* ------------------------------------------------------------------ */
|
|
115
|
+
const RANK_BADGE = { 1: 'bg-cyan-400/20 text-cyan-400', 2: 'bg-white/20 text-white', 3: 'bg-cyan-300/20 text-cyan-300' };
|
|
116
|
+
function MemberRanking({ territoryId }) {
|
|
117
|
+
const { data: raw, loading } = (0, auth_react_1.useTerritoryRanking)(territoryId, { page_size: 10 });
|
|
118
|
+
const rankList = (0, react_1.useMemo)(() => {
|
|
119
|
+
if (!raw)
|
|
120
|
+
return [];
|
|
121
|
+
return Array.isArray(raw) ? raw : raw.data ?? [];
|
|
122
|
+
}, [raw]);
|
|
123
|
+
if (loading)
|
|
124
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-6", children: (0, jsx_runtime_1.jsx)("div", { className: "h-64 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(Spinner, {}) }) });
|
|
125
|
+
if (rankList.length === 0)
|
|
126
|
+
return null;
|
|
127
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-4 flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconShield, { className: "w-4 h-4 text-cyan-400" }), "Member Contribution Ranking"] }), (0, jsx_runtime_1.jsx)("div", { className: "space-y-2", children: rankList.map((m, idx) => {
|
|
128
|
+
const rank = m.rank ?? idx + 1;
|
|
129
|
+
const name = m.nickname || m.display_name || 'Unknown';
|
|
130
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 p-2 bg-neutral-800 rounded hover:bg-neutral-700 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-8 text-center", children: rank <= 3 ? ((0, jsx_runtime_1.jsxs)("span", { className: `inline-block px-1.5 py-0.5 rounded text-xs font-bold ${RANK_BADGE[rank] ?? ''}`, children: ["#", rank] })) : ((0, jsx_runtime_1.jsxs)("span", { className: "text-neutral-500 font-mono text-sm", children: ["#", rank] })) }), (0, jsx_runtime_1.jsx)("div", { className: "w-8 h-8 rounded-full bg-neutral-700 flex items-center justify-center text-xs text-white font-bold flex-shrink-0", children: name.slice(0, 2).toUpperCase() }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white text-sm truncate", children: name }), m.email && (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-xs truncate", children: m.email })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right flex-shrink-0", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white font-mono font-medium text-sm", children: (m.contribution ?? 0).toLocaleString() }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-500 text-xs ml-1", children: "MCD" })] })] }, m.user_id || idx));
|
|
131
|
+
}) })] }));
|
|
132
|
+
}
|
|
133
|
+
/* ------------------------------------------------------------------ */
|
|
134
|
+
/* KPI History Chart (recharts AreaChart) */
|
|
135
|
+
/* ------------------------------------------------------------------ */
|
|
136
|
+
function KPIHistoryChart({ territoryId }) {
|
|
137
|
+
const { data: raw, loading } = (0, auth_react_1.useTerritoryKPI)(territoryId);
|
|
138
|
+
const uid = (0, react_1.useId)();
|
|
139
|
+
const chartData = (0, react_1.useMemo)(() => {
|
|
140
|
+
if (!raw)
|
|
141
|
+
return [];
|
|
142
|
+
if (Array.isArray(raw))
|
|
143
|
+
return raw;
|
|
144
|
+
return raw.data ?? [];
|
|
145
|
+
}, [raw]);
|
|
146
|
+
if (loading)
|
|
147
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-6", children: (0, jsx_runtime_1.jsx)("div", { className: "h-64 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(Spinner, {}) }) });
|
|
148
|
+
if (chartData.length === 0)
|
|
149
|
+
return null;
|
|
150
|
+
const gradMember = `kpi-member-${uid}`;
|
|
151
|
+
const gradVolume = `kpi-volume-${uid}`;
|
|
152
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-4 flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconEdit3, { className: "w-4 h-4 text-cyan-400" }), "KPI History"] }), (0, jsx_runtime_1.jsx)("div", { className: "h-64", children: (0, jsx_runtime_1.jsx)(recharts_1.ResponsiveContainer, { width: "100%", height: "100%", children: (0, jsx_runtime_1.jsxs)(recharts_1.AreaChart, { data: chartData, margin: { top: 5, right: 10, left: 0, bottom: 5 }, children: [(0, jsx_runtime_1.jsxs)("defs", { children: [(0, jsx_runtime_1.jsxs)("linearGradient", { id: gradMember, x1: "0", y1: "0", x2: "0", y2: "1", children: [(0, jsx_runtime_1.jsx)("stop", { offset: "5%", stopColor: "#22d3ee", stopOpacity: 0.3 }), (0, jsx_runtime_1.jsx)("stop", { offset: "95%", stopColor: "#22d3ee", stopOpacity: 0 })] }), (0, jsx_runtime_1.jsxs)("linearGradient", { id: gradVolume, x1: "0", y1: "0", x2: "0", y2: "1", children: [(0, jsx_runtime_1.jsx)("stop", { offset: "5%", stopColor: "#ffffff", stopOpacity: 0.3 }), (0, jsx_runtime_1.jsx)("stop", { offset: "95%", stopColor: "#ffffff", stopOpacity: 0 })] })] }), (0, jsx_runtime_1.jsx)(recharts_1.CartesianGrid, { strokeDasharray: "3 3", stroke: "#404040" }), (0, jsx_runtime_1.jsx)(recharts_1.XAxis, { dataKey: "date", tick: { fill: '#a3a3a3', fontSize: 11 }, axisLine: { stroke: '#525252' } }), (0, jsx_runtime_1.jsx)(recharts_1.YAxis, { domain: [0, 100], tick: { fill: '#a3a3a3', fontSize: 11 }, axisLine: { stroke: '#525252' }, tickFormatter: (v) => `${v}%` }), (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { contentStyle: { backgroundColor: '#171717', border: '1px solid #404040', borderRadius: '8px' }, labelStyle: { color: '#a3a3a3' }, formatter: (value) => [`${Number(value).toFixed(1)}%`, ''] }), (0, jsx_runtime_1.jsx)(recharts_1.Area, { type: "monotone", dataKey: "member_progress", name: "Member Progress", stroke: "#22d3ee", strokeWidth: 2, fill: `url(#${gradMember})` }), (0, jsx_runtime_1.jsx)(recharts_1.Area, { type: "monotone", dataKey: "volume_progress", name: "Volume Progress", stroke: "#ffffff", strokeWidth: 2, fill: `url(#${gradVolume})` })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-center gap-6 mt-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-3 h-3 rounded-full bg-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Member Progress" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-3 h-3 rounded-full bg-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Volume Progress" })] })] })] }));
|
|
153
|
+
}
|
|
154
|
+
/* ------------------------------------------------------------------ */
|
|
155
|
+
/* Edit Territory Dialog */
|
|
156
|
+
/* ------------------------------------------------------------------ */
|
|
157
|
+
function EditTerritoryDialog({ territory, open, onClose, onSaved }) {
|
|
158
|
+
const { update, loading: updating } = (0, auth_react_1.useTerritoryUpdate)();
|
|
159
|
+
const [name, setName] = (0, react_1.useState)(territory.unit_name);
|
|
160
|
+
const [desc, setDesc] = (0, react_1.useState)(territory.description || '');
|
|
161
|
+
const [error, setError] = (0, react_1.useState)('');
|
|
162
|
+
const handleSave = (0, react_1.useCallback)(async () => {
|
|
163
|
+
if (!name.trim()) {
|
|
164
|
+
setError('Name is required');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
setError('');
|
|
169
|
+
await update(territory.unit_id, { unit_name: name, description: desc });
|
|
170
|
+
onSaved();
|
|
171
|
+
onClose();
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
setError(e.message || 'Update failed');
|
|
175
|
+
}
|
|
176
|
+
}, [update, territory.unit_id, name, desc, onSaved, onClose]);
|
|
177
|
+
if (!open)
|
|
178
|
+
return null;
|
|
179
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", onClick: onClose, children: [(0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 bg-black/60" }), (0, jsx_runtime_1.jsxs)("div", { className: "relative bg-neutral-900 border border-neutral-700 rounded-lg w-full max-w-lg p-6 space-y-4 mx-4", onClick: (e) => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-bold text-lg", children: "Edit Territory" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-neutral-500 text-xs font-mono mt-1", children: [territory.unit_type, " \u00B7 ", territory.full_path || territory.short_id || territory.unit_id] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-neutral-400 tracking-wider block mb-1", children: "unit_name *" }), (0, jsx_runtime_1.jsx)("input", { value: name, onChange: (e) => setName(e.target.value), className: "w-full bg-neutral-800 border border-neutral-700 text-white px-3 py-2 rounded text-sm focus:border-cyan-400/50 outline-none" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-neutral-400 tracking-wider block mb-1", children: "description" }), (0, jsx_runtime_1.jsx)("textarea", { value: desc, onChange: (e) => setDesc(e.target.value), rows: 3, className: "w-full bg-neutral-800 border border-neutral-700 text-white px-3 py-2 rounded text-sm focus:border-cyan-400/50 outline-none resize-none" })] })] }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-red-400 text-xs", children: error }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: onClose, disabled: updating, className: "px-4 py-2 text-sm text-neutral-400 border border-neutral-700 rounded hover:bg-neutral-800 transition-colors", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleSave, disabled: updating, className: "px-4 py-2 text-sm text-white bg-cyan-700 hover:bg-cyan-600 rounded transition-colors disabled:opacity-50", children: updating ? 'Saving...' : 'Save' })] })] })] }));
|
|
180
|
+
}
|
|
181
|
+
/* ------------------------------------------------------------------ */
|
|
182
|
+
/* Detail View (full) */
|
|
183
|
+
/* ------------------------------------------------------------------ */
|
|
84
184
|
function TerritoryDetailView({ territoryId, territory, onBack }) {
|
|
85
185
|
const { data: detailedStats, loading: statsLoading } = (0, auth_react_1.useTerritoryDetailedStats)(territoryId);
|
|
86
186
|
const { data: members, loading: membersLoading } = (0, auth_react_1.useTerritoryMembers)(territoryId);
|
|
187
|
+
const [editOpen, setEditOpen] = (0, react_1.useState)(false);
|
|
87
188
|
const stats = detailedStats;
|
|
88
189
|
const memberList = Array.isArray(members) ? members : [];
|
|
89
190
|
const unitType = (territory?.unit_type || 'station');
|
|
90
191
|
const techBonus = TECH_BONUS[unitType.toLowerCase()] ?? 0;
|
|
91
|
-
const memberCount = territory?.member_count ?? stats?.stats?.member_count ?? 0;
|
|
92
|
-
const maxCapacity = territory?.max_capacity ?? stats?.stats?.max_capacity ?? 0;
|
|
93
|
-
const vaultBalance = territory?.vault_balance ?? stats?.stats?.vault_balance ?? 0;
|
|
192
|
+
const memberCount = territory?.member_count ?? stats?.stats?.member_count ?? stats?.metrics?.member_count ?? 0;
|
|
193
|
+
const maxCapacity = territory?.max_capacity ?? stats?.stats?.max_capacity ?? stats?.metrics?.max_capacity ?? 0;
|
|
194
|
+
const vaultBalance = territory?.vault_balance ?? stats?.stats?.vault_balance ?? stats?.metrics?.vault_mcd ?? 0;
|
|
94
195
|
const occupancy = maxCapacity > 0 ? Math.round((memberCount / maxCapacity) * 100) : 0;
|
|
95
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: onBack, className: "flex items-center gap-2 text-sm text-neutral-400 hover:text-white transition-colors bg-transparent border-none cursor-pointer", children: [(0, jsx_runtime_1.jsx)(IconArrowLeft, { className: "w-4 h-4" }), "Back to list"] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-5", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-24 h-24 bg-neutral-800 rounded-lg flex items-center justify-center overflow-hidden flex-shrink-0", children: territory?.image_url ? ((0, jsx_runtime_1.jsx)("img", { src: territory.image_url, alt: territory.unit_name, className: "w-full h-full object-cover" })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-neutral-600", children: getTypeIcon(unitType, 'w-10 h-10') })) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 flex-wrap", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-xl font-bold text-white", children: territory?.unit_name ?? territoryId }), territory?.short_id && ((0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-500 font-mono", children: territory.short_id })), (0, jsx_runtime_1.jsxs)("span", { className: `border px-1.5 py-0.5 rounded text-xs capitalize ${getTypeBadgeColor(unitType)}`, children: [getTypeIcon(unitType, 'w-3 h-3 inline-block -mt-0.5 mr-1'), unitType] }), territory?.manager_display_name && ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1 text-xs text-emerald-400 border border-emerald-400/30 px-1.5 py-0.5 rounded", children: [(0, jsx_runtime_1.jsx)(IconShield, { className: "w-3 h-3" }), "Magistrate: ", territory.manager_display_name] }))] }), territory?.full_path && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-500 text-sm font-mono mt-1", children: territory.full_path })), territory?.description && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-2", children: territory.description }))] })] }) }), statsLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-24" }, i)) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-4 h-4 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Members" })] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-2xl font-bold text-white font-mono", children: [fmt(memberCount), (0, jsx_runtime_1.jsxs)("span", { className: "text-sm text-neutral-500 font-normal", children: ["/", fmt(maxCapacity)] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconVault, { className: "w-4 h-4 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Vault MCD" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-2xl font-bold text-white font-mono", children: fmt(Math.round(vaultBalance)) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconZap, { className: "w-4 h-4 text-yellow-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Tech Bonus" })] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-2xl font-bold text-yellow-400 font-mono", children: ["+", stats?.tech_bonus ?? techBonus, "%"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconSettings, { className: "w-4 h-4 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Occupancy" })] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-2xl font-bold text-white font-mono", children: [occupancy, "%"] })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-4 flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconEdit3, { className: "w-4 h-4 text-cyan-400" }), "KPI Progress"] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Occupancy Rate" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-sm text-white font-mono", children: [occupancy, "%"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 bg-neutral-800 rounded-full overflow-hidden", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-cyan-400 rounded-full transition-all duration-500", style: { width: `${Math.min(occupancy, 100)}%` } }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: "Vault Balance" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-sm text-white font-mono", children: [fmt(Math.round(vaultBalance)), " MCD"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 bg-neutral-800 rounded-full overflow-hidden", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-cyan-400 rounded-full transition-all duration-500", style: { width: `${Math.min(vaultBalance > 0 ? Math.max(Math.log10(vaultBalance) * 10, 5) : 0, 100)}%` } }) })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-3 flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconVault, { className: "w-4 h-4 text-cyan-400" }), "Distribution Mechanism"] }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm leading-relaxed", children: "Each territory vault distributes 1% of its MCD balance daily to all active miners within the territory. The distribution is proportional to each miner's mining activity. Vault balances are replenished through companion yield from mining operations (30% of companion output as MCD) and monthly recycling cycles." })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "p-4 border-b border-neutral-700/50", children: (0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-4 h-4 text-cyan-400" }), "Members (", memberList.length, ")"] }) }), (0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: membersLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "p-6 flex justify-center", children: (0, jsx_runtime_1.jsx)(Spinner, {}) })) : memberList.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "p-8 text-center text-neutral-500 text-sm", children: "No members found" })) : ((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: "border-b border-neutral-700/50", children: [(0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Name / UID" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Role" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Email" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Joined" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: memberList.map((member, idx) => ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-neutral-800/50 hover:bg-neutral-800/30", children: [(0, jsx_runtime_1.jsxs)("td", { className: "px-4 py-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white", children: member.display_name || member.username || 'Unknown' }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-xs font-mono", children: member.uid ? `${member.uid.slice(0, 12)}...` : '-' })] }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300 capitalize", children: member.role || member.level_name || 'Miner' }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 font-mono text-xs", children: member.email ? (member.email.length > 20 ? member.email.slice(0, 20) + '...' : member.email) : '-' }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsxs)("span", { className: "text-neutral-400 flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconCalendar, { className: "w-3 h-3" }), member.joined_at || member.created_at
|
|
96
|
-
? new Date(member.joined_at || member.created_at).toLocaleDateString()
|
|
97
|
-
: '-'] }) })] }, member.uid || idx))) })] })) })] })] }));
|
|
196
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: onBack, className: "flex items-center gap-2 text-sm text-neutral-400 hover:text-white transition-colors bg-transparent border-none cursor-pointer", children: [(0, jsx_runtime_1.jsx)(IconArrowLeft, { className: "w-4 h-4" }), "Back to list"] }), territory && ((0, jsx_runtime_1.jsxs)("button", { onClick: () => setEditOpen(true), className: "flex items-center gap-1.5 px-3 py-1.5 text-sm text-white bg-cyan-700 hover:bg-cyan-600 rounded transition-colors", children: [(0, jsx_runtime_1.jsx)(IconEdit3, { className: "w-3.5 h-3.5" }), "Edit"] }))] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-5", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-28 h-28 bg-neutral-800 rounded-lg flex items-center justify-center overflow-hidden flex-shrink-0", children: territory?.image_url ? ((0, jsx_runtime_1.jsx)("img", { src: territory.image_url, alt: territory.unit_name, className: "w-full h-full object-cover" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center text-neutral-600", children: [getTypeIcon(unitType, 'w-10 h-10'), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] mt-1 capitalize", children: unitType })] })) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 flex-wrap", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-xl font-bold text-white", children: territory?.unit_name ?? territoryId }), territory?.short_id && ((0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400 font-mono bg-neutral-800 px-2 py-0.5 rounded", children: territory.short_id })), (0, jsx_runtime_1.jsx)("span", { className: `border px-1.5 py-0.5 rounded text-xs capitalize ${getTypeBadgeColor(unitType)}`, children: unitType }), occupancy >= 90 ? ((0, jsx_runtime_1.jsx)("span", { className: "text-xs bg-white/20 text-white px-1.5 py-0.5 rounded", children: "Qualified" })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-xs bg-neutral-500/20 text-neutral-400 px-1.5 py-0.5 rounded", children: "Not Qualified" }))] }), territory?.manager_display_name && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mt-2 text-xs text-emerald-400", children: [(0, jsx_runtime_1.jsx)(IconShield, { className: "w-3.5 h-3.5" }), "Magistrate: ", territory.manager_display_name] })), territory?.full_path && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-500 text-sm font-mono mt-1", children: territory.full_path })), territory?.description && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-2", children: territory.description }))] })] }) }), statsLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-24" }, i)) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-5 h-5 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Members" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-2xl font-bold text-white font-mono", children: fmt(memberCount) }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-neutral-500 mt-1", children: ["Capacity: ", (0, jsx_runtime_1.jsx)("span", { className: "font-mono", children: fmt(maxCapacity) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconVault, { className: "w-5 h-5 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Vault Balance" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-2xl font-bold text-white font-mono", children: fmt(Math.round(vaultBalance)) }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "MCD" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconZap, { className: "w-5 h-5 text-yellow-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Tech Bonus" })] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-2xl font-bold text-white font-mono", children: ["+", stats?.tech_bonus ?? techBonus, "%"] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Mining output bonus" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconSettings, { className: "w-5 h-5 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400", children: "Occupancy" })] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-2xl font-bold text-white font-mono", children: [occupancy, "%"] }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Members / Capacity" })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-4 flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconEdit3, { className: "w-4 h-4 text-cyan-400" }), "KPI Progress"] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between text-sm mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Members" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-mono", children: [fmt(memberCount), " / ", fmt(maxCapacity)] })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 bg-neutral-800 rounded-full overflow-hidden", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-cyan-400 rounded-full transition-all duration-500", style: { width: `${Math.min(occupancy, 100)}%` } }) }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-neutral-500 font-mono mt-1", children: [occupancy, "% filled"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between text-sm mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Vault Balance" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-mono", children: [fmt(Math.round(vaultBalance)), " MCD"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 bg-neutral-800 rounded-full overflow-hidden", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-cyan-400 rounded-full transition-all duration-500", style: { width: `${Math.min(vaultBalance > 0 ? Math.max(Math.log10(vaultBalance) * 10, 5) : 0, 100)}%` } }) }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Current vault funds" })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors p-6", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold mb-3 flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconSettings, { className: "w-4 h-4 text-cyan-400" }), "Distribution Mechanism"] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsx)("h4", { className: "text-white font-semibold text-sm mb-2", children: "Auto Distribution by Contribution" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm", children: "Vault MCD is distributed daily at 1% of balance, allocated to miners proportional to their mining activity." }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-500 text-xs mt-2", children: "Distribution ratio: Miners 100% (by contribution)" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(IncomeChart, { territoryId: territoryId }), (0, jsx_runtime_1.jsx)(MemberRanking, { territoryId: territoryId })] }), (0, jsx_runtime_1.jsx)(KPIHistoryChart, { territoryId: territoryId }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "p-4 border-b border-neutral-700/50", children: (0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-semibold flex items-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-4 h-4 text-cyan-400" }), "Members (", memberList.length, ")"] }) }), (0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: membersLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "p-6 flex justify-center", children: (0, jsx_runtime_1.jsx)(Spinner, {}) })) : memberList.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "p-8 text-center text-neutral-500 text-sm", children: "No members found" })) : ((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: "border-b border-neutral-700/50", children: [(0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Name / UID" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Role" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Email" }), (0, jsx_runtime_1.jsx)("th", { className: "text-left px-4 py-3 text-neutral-400 font-medium", children: "Joined" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: memberList.map((member, idx) => ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-neutral-800/50 hover:bg-neutral-800/30", children: [(0, jsx_runtime_1.jsxs)("td", { className: "px-4 py-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white", children: member.display_name || member.username || 'Unknown' }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-xs font-mono", children: member.uid ? `${member.uid.slice(0, 12)}...` : '-' })] }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300 capitalize", children: member.role || member.level_name || 'Miner' }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 font-mono text-xs", children: member.email ? (member.email.length > 20 ? member.email.slice(0, 20) + '...' : member.email) : '-' }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsxs)("span", { className: "text-neutral-400 flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconCalendar, { className: "w-3 h-3" }), member.joined_at || member.created_at ? new Date(member.joined_at || member.created_at).toLocaleDateString() : '-'] }) })] }, member.uid || idx))) })] })) })] }), territory && ((0, jsx_runtime_1.jsx)(EditTerritoryDialog, { territory: territory, open: editOpen, onClose: () => setEditOpen(false), onSaved: () => { } }))] }));
|
|
98
197
|
}
|
|
99
198
|
/* ------------------------------------------------------------------ */
|
|
100
199
|
/* Main Component */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { MicrocosmMenuSection } from './components/menu-section';
|
|
2
2
|
export type { MicrocosmMenuSectionProps } from './components/menu-section';
|
|
3
|
-
export { blockchainMenu, web3OsMenu, dashboardMenu, microcosmMenuGroups, getAllMenuItems, resolveMenuPath, } from './menu-config';
|
|
4
|
-
export type { MicrocosmMenuItem, MicrocosmMenuGroup } from './menu-config';
|
|
3
|
+
export { blockchainMenu, web3OsMenu, dashboardMenu, microcosmMenuGroups, getAllMenuItems, resolveMenuPath, getMenuTitle, getMenuDescription, } from './menu-config';
|
|
4
|
+
export type { MicrocosmMenuItem, MicrocosmMenuGroup, MenuLocale } from './menu-config';
|
|
5
5
|
export { TerminalCard, StatBox, TerminalCommand, TerminalPageHeader, TerminalLoading, TerminalError, TerminalEmpty, TerminalBadge, TerminalDataRow, TerminalProgress, } from './components/terminal';
|
|
6
6
|
export { TerminalTable } from './components/terminal-table';
|
|
7
7
|
export type { TerminalTableColumn, TerminalTableProps } from './components/terminal-table';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MicrocosmVotingPage = exports.MicrocosmOrganizationPage = exports.MicrocosmTerritoryPage = exports.MicrocosmAuctionPage = exports.MicrocosmMCDPage = exports.MicrocosmMiningPage = exports.MicrocosmWalletPage = exports.MicrocosmLendingPage = exports.MicrocosmFragmentPage = exports.MicrocosmLockPeriods = exports.MicrocosmMCDStats = exports.MicrocosmMCCTokenStats = exports.MicrocosmEcosystemStats = exports.MicrocosmMyMining = exports.MicrocosmMiningWeight = exports.MicrocosmMintingStats = exports.MicrocosmPriceChart = exports.MicrocosmAssetsSummary = exports.MicrocosmQuickActions = exports.MicrocosmMarketBar = exports.MicrocosmDashboardOverview = exports.KPIRadialChart = exports.VoteResultBar = exports.MiningProgressBar = exports.TerritoryCard = exports.TerminalTooltip = exports.TerminalInput = exports.TerminalCountdown = exports.TerminalDialog = exports.TerminalTabs = exports.TerminalTable = exports.TerminalProgress = exports.TerminalDataRow = exports.TerminalBadge = exports.TerminalEmpty = exports.TerminalError = exports.TerminalLoading = exports.TerminalPageHeader = exports.TerminalCommand = exports.StatBox = exports.TerminalCard = exports.resolveMenuPath = exports.getAllMenuItems = exports.microcosmMenuGroups = exports.dashboardMenu = exports.web3OsMenu = exports.blockchainMenu = exports.MicrocosmMenuSection = void 0;
|
|
3
|
+
exports.MicrocosmVotingPage = exports.MicrocosmOrganizationPage = exports.MicrocosmTerritoryPage = exports.MicrocosmAuctionPage = exports.MicrocosmMCDPage = exports.MicrocosmMiningPage = exports.MicrocosmWalletPage = exports.MicrocosmLendingPage = exports.MicrocosmFragmentPage = exports.MicrocosmLockPeriods = exports.MicrocosmMCDStats = exports.MicrocosmMCCTokenStats = exports.MicrocosmEcosystemStats = exports.MicrocosmMyMining = exports.MicrocosmMiningWeight = exports.MicrocosmMintingStats = exports.MicrocosmPriceChart = exports.MicrocosmAssetsSummary = exports.MicrocosmQuickActions = exports.MicrocosmMarketBar = exports.MicrocosmDashboardOverview = exports.KPIRadialChart = exports.VoteResultBar = exports.MiningProgressBar = exports.TerritoryCard = exports.TerminalTooltip = exports.TerminalInput = exports.TerminalCountdown = exports.TerminalDialog = exports.TerminalTabs = exports.TerminalTable = exports.TerminalProgress = exports.TerminalDataRow = exports.TerminalBadge = exports.TerminalEmpty = exports.TerminalError = exports.TerminalLoading = exports.TerminalPageHeader = exports.TerminalCommand = exports.StatBox = exports.TerminalCard = exports.getMenuDescription = exports.getMenuTitle = exports.resolveMenuPath = exports.getAllMenuItems = exports.microcosmMenuGroups = exports.dashboardMenu = exports.web3OsMenu = exports.blockchainMenu = exports.MicrocosmMenuSection = void 0;
|
|
4
4
|
// AI-generated · AI-managed · AI-maintained
|
|
5
5
|
var menu_section_1 = require("./components/menu-section");
|
|
6
6
|
Object.defineProperty(exports, "MicrocosmMenuSection", { enumerable: true, get: function () { return menu_section_1.MicrocosmMenuSection; } });
|
|
@@ -11,6 +11,8 @@ Object.defineProperty(exports, "dashboardMenu", { enumerable: true, get: functio
|
|
|
11
11
|
Object.defineProperty(exports, "microcosmMenuGroups", { enumerable: true, get: function () { return menu_config_1.microcosmMenuGroups; } });
|
|
12
12
|
Object.defineProperty(exports, "getAllMenuItems", { enumerable: true, get: function () { return menu_config_1.getAllMenuItems; } });
|
|
13
13
|
Object.defineProperty(exports, "resolveMenuPath", { enumerable: true, get: function () { return menu_config_1.resolveMenuPath; } });
|
|
14
|
+
Object.defineProperty(exports, "getMenuTitle", { enumerable: true, get: function () { return menu_config_1.getMenuTitle; } });
|
|
15
|
+
Object.defineProperty(exports, "getMenuDescription", { enumerable: true, get: function () { return menu_config_1.getMenuDescription; } });
|
|
14
16
|
var terminal_1 = require("./components/terminal");
|
|
15
17
|
Object.defineProperty(exports, "TerminalCard", { enumerable: true, get: function () { return terminal_1.TerminalCard; } });
|
|
16
18
|
Object.defineProperty(exports, "StatBox", { enumerable: true, get: function () { return terminal_1.StatBox; } });
|
package/dist/menu-config.d.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import { type LucideIcon } from 'lucide-react';
|
|
2
|
+
export type MenuLocale = 'en' | 'zh' | 'ja' | 'ko';
|
|
2
3
|
export interface MicrocosmMenuItem {
|
|
3
4
|
title: string;
|
|
5
|
+
titles?: Partial<Record<MenuLocale, string>>;
|
|
4
6
|
key: string;
|
|
5
7
|
path: string;
|
|
6
8
|
icon: LucideIcon;
|
|
7
9
|
description?: string;
|
|
10
|
+
descriptions?: Partial<Record<MenuLocale, string>>;
|
|
8
11
|
badge?: string;
|
|
9
12
|
}
|
|
10
13
|
export interface MicrocosmMenuGroup {
|
|
11
14
|
title: string;
|
|
15
|
+
titles?: Partial<Record<MenuLocale, string>>;
|
|
12
16
|
key: string;
|
|
13
17
|
icon: LucideIcon;
|
|
14
18
|
items: MicrocosmMenuItem[];
|
|
15
19
|
}
|
|
20
|
+
/** Resolve localized title — falls back to `item.title` (English) */
|
|
21
|
+
export declare function getMenuTitle(item: {
|
|
22
|
+
title: string;
|
|
23
|
+
titles?: Partial<Record<MenuLocale, string>>;
|
|
24
|
+
}, locale?: MenuLocale): string;
|
|
25
|
+
/** Resolve localized description */
|
|
26
|
+
export declare function getMenuDescription(item: MicrocosmMenuItem, locale?: MenuLocale): string;
|
|
16
27
|
export declare const dashboardMenu: MicrocosmMenuGroup;
|
|
17
28
|
export declare const blockchainMenu: MicrocosmMenuGroup;
|
|
18
29
|
export declare const web3OsMenu: MicrocosmMenuGroup;
|
package/dist/menu-config.js
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.microcosmMenuGroups = exports.web3OsMenu = exports.blockchainMenu = exports.dashboardMenu = void 0;
|
|
4
|
+
exports.getMenuTitle = getMenuTitle;
|
|
5
|
+
exports.getMenuDescription = getMenuDescription;
|
|
4
6
|
exports.getAllMenuItems = getAllMenuItems;
|
|
5
7
|
exports.resolveMenuPath = resolveMenuPath;
|
|
6
8
|
// AI-generated · AI-managed · AI-maintained
|
|
7
9
|
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
/** Resolve localized title — falls back to `item.title` (English) */
|
|
11
|
+
function getMenuTitle(item, locale) {
|
|
12
|
+
if (!locale || !item.titles)
|
|
13
|
+
return item.title;
|
|
14
|
+
return item.titles[locale] ?? item.title;
|
|
15
|
+
}
|
|
16
|
+
/** Resolve localized description */
|
|
17
|
+
function getMenuDescription(item, locale) {
|
|
18
|
+
if (!locale || !item.descriptions)
|
|
19
|
+
return item.description ?? '';
|
|
20
|
+
return item.descriptions[locale] ?? item.description ?? '';
|
|
21
|
+
}
|
|
8
22
|
exports.dashboardMenu = {
|
|
9
23
|
title: 'Overview',
|
|
10
24
|
key: 'overview',
|
|
@@ -54,31 +68,57 @@ exports.web3OsMenu = {
|
|
|
54
68
|
items: [
|
|
55
69
|
{
|
|
56
70
|
title: 'Auctions',
|
|
71
|
+
titles: { zh: '拍卖', ja: 'Auctions', ko: 'Auctions' },
|
|
57
72
|
key: 'auctions',
|
|
58
73
|
path: '/mcc/auctions',
|
|
59
74
|
icon: lucide_react_1.Gift,
|
|
60
75
|
description: 'Territory auction bidding',
|
|
76
|
+
descriptions: { zh: '领地拍卖竞价', ja: '領地オークション', ko: '영토 경매' },
|
|
61
77
|
},
|
|
62
78
|
{
|
|
63
79
|
title: 'Territories',
|
|
80
|
+
titles: { zh: '领地管理', ja: 'Territories', ko: 'Territories' },
|
|
64
81
|
key: 'territory',
|
|
65
82
|
path: '/user-system/territory',
|
|
66
83
|
icon: lucide_react_1.Building2,
|
|
67
84
|
description: 'Territory list and details',
|
|
85
|
+
descriptions: { zh: '领地列表与详情', ja: '領地一覧と詳細', ko: '영토 목록 및 상세' },
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
title: 'NFT Fragments',
|
|
89
|
+
titles: { zh: 'NFT 碎片化', ja: 'NFT Fragments', ko: 'NFT Fragments' },
|
|
90
|
+
key: 'fragments',
|
|
91
|
+
path: '/mcc/fragments',
|
|
92
|
+
icon: lucide_react_1.Puzzle,
|
|
93
|
+
description: 'Fractionalize territory NFTs',
|
|
94
|
+
descriptions: { zh: '领地 NFT 碎片化交易', ja: 'NFTフラクション化', ko: 'NFT 분할화' },
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: 'Lending',
|
|
98
|
+
titles: { zh: '去中心化借贷', ja: 'Lending', ko: 'Lending' },
|
|
99
|
+
key: 'lending',
|
|
100
|
+
path: '/mcc/lending',
|
|
101
|
+
icon: lucide_react_1.Landmark,
|
|
102
|
+
description: 'Borrow MCC with NFT collateral',
|
|
103
|
+
descriptions: { zh: 'NFT 抵押借贷 MCC', ja: 'NFT担保レンディング', ko: 'NFT 담보 대출' },
|
|
68
104
|
},
|
|
69
105
|
{
|
|
70
106
|
title: 'Voting',
|
|
107
|
+
titles: { zh: '投票', ja: 'Voting', ko: 'Voting' },
|
|
71
108
|
key: 'voting',
|
|
72
109
|
path: '/mcc/voting',
|
|
73
110
|
icon: lucide_react_1.Vote,
|
|
74
111
|
description: 'Community proposal voting',
|
|
112
|
+
descriptions: { zh: '社区提案投票', ja: '提案投票', ko: '제안 투표' },
|
|
75
113
|
},
|
|
76
114
|
{
|
|
77
115
|
title: 'Organization',
|
|
116
|
+
titles: { zh: '组织', ja: 'Organization', ko: 'Organization' },
|
|
78
117
|
key: 'organization',
|
|
79
118
|
path: '/user-system/organization',
|
|
80
119
|
icon: lucide_react_1.Users,
|
|
81
120
|
description: 'Organization structure',
|
|
121
|
+
descriptions: { zh: '组织架构管理', ja: '組織構造', ko: '조직 구조' },
|
|
82
122
|
},
|
|
83
123
|
],
|
|
84
124
|
};
|