@microcosmmoney/portal-react 3.0.0 → 3.1.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.
- package/dist/components/dashboard/assets-summary.d.ts +2 -1
- package/dist/components/dashboard/assets-summary.js +11 -6
- package/dist/components/dashboard/dashboard-overview.d.ts +2 -1
- package/dist/components/dashboard/dashboard-overview.js +11 -2
- package/dist/components/dashboard/ecosystem-stats.d.ts +4 -1
- package/dist/components/dashboard/ecosystem-stats.js +12 -9
- package/dist/components/dashboard/lock-periods.d.ts +4 -1
- package/dist/components/dashboard/lock-periods.js +2 -2
- package/dist/components/dashboard/market-overview-bar.d.ts +4 -1
- package/dist/components/dashboard/market-overview-bar.js +9 -6
- package/dist/components/dashboard/mcc-token-stats.d.ts +4 -1
- package/dist/components/dashboard/mcc-token-stats.js +12 -9
- package/dist/components/dashboard/mcd-stats.d.ts +4 -1
- package/dist/components/dashboard/mcd-stats.js +14 -11
- package/dist/components/dashboard/mining-weight.d.ts +4 -1
- package/dist/components/dashboard/mining-weight.js +10 -7
- package/dist/components/dashboard/minting-stats.d.ts +4 -1
- package/dist/components/dashboard/minting-stats.js +6 -3
- package/dist/components/dashboard/my-mining.d.ts +2 -1
- package/dist/components/dashboard/my-mining.js +4 -2
- package/dist/components/dashboard/price-chart.d.ts +4 -1
- package/dist/components/dashboard/price-chart.js +6 -4
- package/dist/components/dashboard/quick-actions.d.ts +2 -1
- package/dist/components/dashboard/quick-actions.js +52 -37
- package/dist/components/territory/territory-page.js +95 -122
- package/dist/index.d.ts +8 -0
- package/package.json +4 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface MicrocosmAssetsSummaryProps {
|
|
2
2
|
basePath?: string;
|
|
3
3
|
onNavigate?: (path: string) => void;
|
|
4
|
+
accentColor?: string;
|
|
4
5
|
}
|
|
5
|
-
export declare function MicrocosmAssetsSummary({ basePath, onNavigate }: MicrocosmAssetsSummaryProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function MicrocosmAssetsSummary({ basePath, onNavigate, accentColor }: MicrocosmAssetsSummaryProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,7 +9,7 @@ const RANK_COLOR = {
|
|
|
9
9
|
recruit: 'text-neutral-500', prospect: 'text-neutral-400', miner: 'text-cyan-300',
|
|
10
10
|
commander: 'text-white', pioneer: 'text-cyan-400', warden: 'text-cyan-300', admiral: 'text-cyan-300',
|
|
11
11
|
};
|
|
12
|
-
function MicrocosmAssetsSummary({ basePath = '', onNavigate }) {
|
|
12
|
+
function MicrocosmAssetsSummary({ basePath = '', onNavigate, accentColor }) {
|
|
13
13
|
const { balance: mccData, loading: mccLoading } = (0, auth_react_1.useMCC)(120000);
|
|
14
14
|
const { balance: mcdData, loading: mcdLoading } = (0, auth_react_1.useMCD)(120000);
|
|
15
15
|
const { data: levelData } = (0, auth_react_1.useUserLevel)();
|
|
@@ -30,10 +30,15 @@ function MicrocosmAssetsSummary({ basePath = '', onNavigate }) {
|
|
|
30
30
|
const nextRank = levelData?.next_level ?? null;
|
|
31
31
|
const progress = levelData?.upgrade_progress?.percentage ?? 0;
|
|
32
32
|
const fmt = (n, d = 2) => n.toLocaleString('en-US', { minimumFractionDigits: d, maximumFractionDigits: d });
|
|
33
|
-
const rankColor =
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const rankColor = accentColor
|
|
34
|
+
? undefined
|
|
35
|
+
: RANK_COLOR[(rank ?? '').toLowerCase()] ?? 'text-neutral-500';
|
|
36
|
+
const rankStyle = accentColor ? { color: accentColor } : undefined;
|
|
37
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
38
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
39
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 lg:grid-cols-5 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors cursor-pointer h-full", onClick: () => onNavigate?.(resolvePath('/mcc/wallet')), role: "button", tabIndex: 0, onKeyDown: (e) => e.key === 'Enter' && onNavigate?.(resolvePath('/mcc/wallet')), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsxs)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" }), (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })] }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "MCC_BALANCE" })] }), (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'text-2xl font-bold font-mono' : 'text-2xl font-bold font-mono text-cyan-400', style: accentColor ? { color: accentColor } : undefined, children: mccLoading
|
|
40
|
+
? (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor })
|
|
36
41
|
: fmt(mccBalance, 3) }), mccUsdValue > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500 font-mono mt-1", children: ["\u2248 $", fmt(mccUsdValue)] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors cursor-pointer h-full", onClick: () => onNavigate?.(resolvePath('/mcc/mcd')), role: "button", tabIndex: 0, onKeyDown: (e) => e.key === 'Enter' && onNavigate?.(resolvePath('/mcc/mcd')), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" }) }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "MCD_BALANCE" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold font-mono text-white", children: mcdLoading
|
|
37
|
-
? (0, jsx_runtime_1.jsx)("span", { className:
|
|
38
|
-
: fmt(mcdAmount) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono mt-1", children: ["in: ", fmt(mcdReceived, 0), " out: ", fmt(mcdSpent, 0)] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "LOCKED" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold font-mono text-white", children: fmt(lockedAmount, 0) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono mt-1", children: [activeLocks.length, " lock period", activeLocks.length !== 1 ? 's' : ''] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "WALLETS" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold font-mono text-white", children: walletCount })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-[10px] font-mono tracking-wider mb-2", children: "RANK" }), (0, jsx_runtime_1.jsx)("div", { className: `text-lg font-bold font-mono ${rankColor}`, children: rank || 'N/A' }), nextRank && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-800 rounded-full h-1.5", children: (0, jsx_runtime_1.jsx)("div", { className:
|
|
42
|
+
? (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor })
|
|
43
|
+
: fmt(mcdAmount) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono mt-1", children: ["in: ", fmt(mcdReceived, 0), " out: ", fmt(mcdSpent, 0)] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "LOCKED" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold font-mono text-white", children: fmt(lockedAmount, 0) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono mt-1", children: [activeLocks.length, " lock period", activeLocks.length !== 1 ? 's' : ''] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-2", children: [(0, jsx_runtime_1.jsx)("svg", { className: "w-3.5 h-3.5 text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" }) }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-[10px] font-mono tracking-wider", children: "WALLETS" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold font-mono text-white", children: walletCount })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-[10px] font-mono tracking-wider mb-2", children: "RANK" }), (0, jsx_runtime_1.jsx)("div", { className: `text-lg font-bold font-mono ${rankColor ?? ''}`, style: rankStyle, children: rank || 'N/A' }), nextRank && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-800 rounded-full h-1.5", children: (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'h-1.5 rounded-full transition-all' : 'bg-cyan-400 h-1.5 rounded-full transition-all', style: { width: `${Math.min(progress, 100)}%`, ...(accentColor ? { backgroundColor: accentColor } : {}) } }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono mt-1", children: [progress.toFixed(0), "% \u2192 ", nextRank] })] }))] })] }));
|
|
39
44
|
}
|
|
@@ -3,5 +3,6 @@ export interface MicrocosmDashboardOverviewProps {
|
|
|
3
3
|
onNavigate?: (path: string) => void;
|
|
4
4
|
showHeader?: boolean;
|
|
5
5
|
headerText?: string;
|
|
6
|
+
accentColor?: string;
|
|
6
7
|
}
|
|
7
|
-
export declare function MicrocosmDashboardOverview({ basePath, onNavigate, showHeader, headerText, }: MicrocosmDashboardOverviewProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function MicrocosmDashboardOverview({ basePath, onNavigate, showHeader, headerText, accentColor, }: MicrocosmDashboardOverviewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -49,6 +49,15 @@ function LazySection({ children, fallback }) {
|
|
|
49
49
|
}, []);
|
|
50
50
|
return (0, jsx_runtime_1.jsx)("div", { ref: ref, children: visible ? children : fallback });
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
/** Convert hex color "#d4a846" to RGB string "212,168,70" */
|
|
53
|
+
function hexToRgb(hex) {
|
|
54
|
+
const h = hex.replace('#', '');
|
|
55
|
+
const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
|
|
56
|
+
return `${(n >> 16) & 255},${(n >> 8) & 255},${n & 255}`;
|
|
57
|
+
}
|
|
58
|
+
function MicrocosmDashboardOverview({ basePath = '', onNavigate, showHeader = true, headerText = 'SHARED NETWORK · SHARED FUTURE', accentColor, }) {
|
|
59
|
+
const rootStyle = accentColor
|
|
60
|
+
? { '--mc-accent': accentColor, '--mc-accent-rgb': hexToRgb(accentColor) }
|
|
61
|
+
: undefined;
|
|
62
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono p-6 space-y-6", style: rootStyle, children: [showHeader && ((0, jsx_runtime_1.jsx)("div", { className: "text-center", children: (0, jsx_runtime_1.jsx)("h1", { className: accentColor ? 'text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold tracking-tight' : 'text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold tracking-tight text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 to-cyan-200', style: accentColor ? { backgroundImage: `linear-gradient(to right, ${accentColor}, ${accentColor}cc)`, WebkitBackgroundClip: 'text', backgroundClip: 'text', color: 'transparent' } : undefined, children: headerText }) })), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(market_overview_bar_1.MicrocosmMarketBar, { accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(quick_actions_1.MicrocosmQuickActions, { basePath: basePath, onNavigate: onNavigate, accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(assets_summary_1.MicrocosmAssetsSummary, { basePath: basePath, onNavigate: onNavigate, accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(price_chart_1.MicrocosmPriceChart, { accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(LazySection, { fallback: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(CardSkeleton, { height: "h-56" }), (0, jsx_runtime_1.jsx)(CardSkeleton, { height: "h-56" })] }), children: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(my_mining_1.MicrocosmMyMining, { detailsPath: `${basePath}/mcc/mining`, onNavigate: onNavigate, accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mining_weight_1.MicrocosmMiningWeight, { accentColor: accentColor }) })] }) }), (0, jsx_runtime_1.jsx)(LazySection, { fallback: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(CardSkeleton, { height: "h-56" }), (0, jsx_runtime_1.jsx)(CardSkeleton, { height: "h-56" })] }), children: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(minting_stats_1.MicrocosmMintingStats, { accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(ecosystem_stats_1.MicrocosmEcosystemStats, { accentColor: accentColor }) })] }) }), (0, jsx_runtime_1.jsx)(LazySection, { fallback: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(CardSkeleton, {}), (0, jsx_runtime_1.jsx)(CardSkeleton, {})] }), children: (0, jsx_runtime_1.jsxs)("div", { className: "grid lg:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mcc_token_stats_1.MicrocosmMCCTokenStats, { accentColor: accentColor }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mcd_stats_1.MicrocosmMCDStats, { accentColor: accentColor }) })] }) }), (0, jsx_runtime_1.jsx)(LazySection, { fallback: (0, jsx_runtime_1.jsx)(CardSkeleton, {}), children: (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(lock_periods_1.MicrocosmLockPeriods, { accentColor: accentColor }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center py-4 space-y-1", children: [(0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'text-xs font-mono' : 'text-xs text-cyan-400/60 font-mono', style: accentColor ? { color: `rgba(${hexToRgb(accentColor)},0.6)` } : undefined, children: "Data refreshes every 4 hours \u00B7 For real-time data, please check on-chain directly" }), (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'text-xs font-mono' : 'text-xs text-cyan-400/60 font-mono', style: accentColor ? { color: `rgba(${hexToRgb(accentColor)},0.6)` } : undefined, children: "\u6570\u636E\u6BCF 4 \u5C0F\u65F6\u66F4\u65B0 \u00B7 \u5373\u65F6\u6570\u636E\u8BF7\u76F4\u63A5\u67E5\u8BE2\u94FE\u4E0A" }), (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'text-xs font-mono' : 'text-xs text-cyan-400/60 font-mono', style: accentColor ? { color: `rgba(${hexToRgb(accentColor)},0.6)` } : undefined, children: "\u30C7\u30FC\u30BF\u306F4\u6642\u9593\u3054\u3068\u306B\u66F4\u65B0 \u00B7 \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30C7\u30FC\u30BF\u306F\u30AA\u30F3\u30C1\u30A7\u30FC\u30F3\u3067\u78BA\u8A8D" }), (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'text-xs font-mono' : 'text-xs text-cyan-400/60 font-mono', style: accentColor ? { color: `rgba(${hexToRgb(accentColor)},0.6)` } : undefined, children: "\uB370\uC774\uD130\uB294 4\uC2DC\uAC04\uB9C8\uB2E4 \uAC31\uC2E0 \u00B7 \uC2E4\uC2DC\uAC04 \uB370\uC774\uD130\uB294 \uC628\uCCB4\uC778\uC5D0\uC11C \uD655\uC778" })] })] }));
|
|
54
63
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmEcosystemStatsProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmEcosystemStats({ accentColor }?: MicrocosmEcosystemStatsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,24 +5,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.MicrocosmEcosystemStats = MicrocosmEcosystemStats;
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
8
|
-
/* Inline SVG icons (16x16,
|
|
9
|
-
const IconUsersTotal = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
10
|
-
const IconActivity = () => ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
11
|
-
const IconHardHat = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
12
|
-
const IconMap = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
13
|
-
const IconGlobe = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
14
|
-
function MicrocosmEcosystemStats() {
|
|
8
|
+
/* Inline SVG icons (16x16, stroke-based) */
|
|
9
|
+
const IconUsersTotal = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "7", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
|
|
10
|
+
const IconActivity = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M22 12h-4l-3 9L9 3l-3 9H2" }) }));
|
|
11
|
+
const IconHardHat = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M2 18a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v2z" }), (0, jsx_runtime_1.jsx)("path", { d: "M10 15V6.5a3.5 3.5 0 0 1 7 0V15" }), (0, jsx_runtime_1.jsx)("path", { d: "M4 15v-5a8 8 0 0 1 16 0v5" })] }));
|
|
12
|
+
const IconMap = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("polygon", { points: "3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21" }), (0, jsx_runtime_1.jsx)("line", { x1: "9", x2: "9", y1: "3", y2: "18" }), (0, jsx_runtime_1.jsx)("line", { x1: "15", x2: "15", y1: "6", y2: "21" })] }));
|
|
13
|
+
const IconGlobe = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 12h20" })] }));
|
|
14
|
+
function MicrocosmEcosystemStats({ accentColor } = {}) {
|
|
15
15
|
const { data: overview, loading: loadingOverview } = (0, auth_react_1.usePlatformStats)();
|
|
16
16
|
const { data: userLevels, loading: loadingUsers } = (0, auth_react_1.useDashboardUserStats)();
|
|
17
17
|
const loading = loadingOverview || loadingUsers;
|
|
18
|
+
const ac = accentColor || '#22d3ee';
|
|
18
19
|
const stats = [
|
|
19
20
|
{ label: 'total_users', value: overview?.total_users ?? userLevels?.total_users, icon: IconUsersTotal },
|
|
20
21
|
{ label: '24h_active', value: overview?.active_users_24h, icon: IconActivity },
|
|
21
22
|
{ label: 'miners', value: userLevels?.miners_and_above ?? overview?.miners_count, icon: IconHardHat },
|
|
22
23
|
{ label: 'territories', value: overview?.total_territories, icon: IconMap },
|
|
23
24
|
];
|
|
24
|
-
|
|
25
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
26
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-4", children: [(0, jsx_runtime_1.jsx)(IconGlobe, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "ECOSYSTEM" })] }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 gap-3", children: stats.map((s) => {
|
|
25
28
|
const Icon = s.icon;
|
|
26
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold font-mono text-white", children: s.value != null ? s.value.toLocaleString() : '--' })] }, s.label));
|
|
29
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold font-mono text-white", children: s.value != null ? s.value.toLocaleString() : '--' })] }, s.label));
|
|
27
30
|
}) }))] }) }));
|
|
28
31
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmLockPeriodsProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmLockPeriods({ accentColor }?: MicrocosmLockPeriodsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -18,12 +18,12 @@ function daysRemaining(endTime) {
|
|
|
18
18
|
const days = Math.ceil(diff / (1000 * 60 * 60 * 24));
|
|
19
19
|
return `${days}d`;
|
|
20
20
|
}
|
|
21
|
-
function MicrocosmLockPeriods() {
|
|
21
|
+
function MicrocosmLockPeriods({ accentColor } = {}) {
|
|
22
22
|
const { data } = (0, auth_react_1.useMCCLocks)();
|
|
23
23
|
const raw = data;
|
|
24
24
|
const locks = Array.isArray(raw) ? raw : raw?.locks ?? [];
|
|
25
25
|
const activeLocks = locks.filter((p) => p.status === 'locked');
|
|
26
26
|
if (activeLocks.length === 0)
|
|
27
27
|
return null;
|
|
28
|
-
return ((0, jsx_runtime_1.jsx)("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-6", children: (0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: activeLocks.map((lock) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-start mb-2", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: lock.reason }), (0, jsx_runtime_1.jsxs)("div", { className:
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)("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-6", children: (0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: activeLocks.map((lock) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-start mb-2", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: lock.reason }), (0, jsx_runtime_1.jsxs)("div", { className: accentColor ? 'text-xl font-bold font-mono mt-1' : 'text-xl font-bold font-mono text-cyan-400 mt-1', style: accentColor ? { color: accentColor } : undefined, children: [(lock.amount ?? 0).toLocaleString(), " MCC"] })] }), (0, jsx_runtime_1.jsx)("span", { className: accentColor ? 'px-2 py-0.5 text-xs font-mono rounded' : 'px-2 py-0.5 bg-cyan-400/20 text-cyan-400 text-xs font-mono rounded', style: accentColor ? { backgroundColor: `${accentColor}33`, color: accentColor } : undefined, children: "LOCKED" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500 space-y-1 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { children: ["unlock_at: ", formatDateTime(lock.lock_end)] }), (0, jsx_runtime_1.jsxs)("div", { children: ["remaining: ", (0, jsx_runtime_1.jsx)("span", { className: accentColor ? '' : 'text-cyan-400', style: accentColor ? { color: accentColor } : undefined, children: daysRemaining(lock.lock_end) })] })] })] }, lock.lock_id))) }) }) }));
|
|
29
29
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmMarketBarProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmMarketBar({ accentColor }?: MicrocosmMarketBarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,8 +12,9 @@ function formatCompact(value) {
|
|
|
12
12
|
return `${(value / 1000).toFixed(1)}K`;
|
|
13
13
|
return value.toFixed(2);
|
|
14
14
|
}
|
|
15
|
-
function MicrocosmMarketBar() {
|
|
15
|
+
function MicrocosmMarketBar({ accentColor } = {}) {
|
|
16
16
|
const { data, loading } = (0, auth_react_1.useMarketData)();
|
|
17
|
+
const ac = accentColor || '#22d3ee';
|
|
17
18
|
if (loading || !data) {
|
|
18
19
|
return ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 mb-6", children: Array.from({ length: 6 }).map((_, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 animate-pulse", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-3 bg-neutral-800 rounded w-16 mb-2" }), (0, jsx_runtime_1.jsx)("div", { className: "h-6 bg-neutral-800 rounded w-24" })] }, i))) }));
|
|
19
20
|
}
|
|
@@ -27,14 +28,16 @@ function MicrocosmMarketBar() {
|
|
|
27
28
|
label: 'MCC_PRICE',
|
|
28
29
|
value: `$${(data.price_usd ?? 0).toFixed(4)}`,
|
|
29
30
|
sub: `${isPositive ? '~+' : '~'}${priceChange24h.toFixed(2)}%`,
|
|
30
|
-
subColor: isPositive ? 'text-cyan-400' : 'text-red-400',
|
|
31
|
-
color:
|
|
31
|
+
subColor: isPositive ? (accentColor ? '' : 'text-cyan-400') : 'text-red-400',
|
|
32
|
+
subStyle: isPositive && accentColor ? { color: accentColor } : undefined,
|
|
33
|
+
color: accentColor ? '' : 'text-cyan-400',
|
|
34
|
+
colorStyle: accentColor ? { color: accentColor } : undefined,
|
|
32
35
|
},
|
|
33
|
-
{ label: '24H_VOLUME', value: `$${formatCompact(data.volume_24h ?? 0)}`, color: 'text-cyan-300' },
|
|
36
|
+
{ label: '24H_VOLUME', value: `$${formatCompact(data.volume_24h ?? 0)}`, color: accentColor ? '' : 'text-cyan-300', colorStyle: accentColor ? { color: accentColor } : undefined },
|
|
34
37
|
{ label: 'LIQUIDITY', value: (data.liquidity_usd ?? 0) > 0 ? `$${formatCompact(data.liquidity_usd)}` : '-', color: 'text-white' },
|
|
35
38
|
{ label: 'FDV', value: (data.fdv ?? 0) > 0 ? `$${formatCompact(data.fdv)}` : '-', color: 'text-white' },
|
|
36
|
-
{ label: '24H_TRADES', value: `${trades}`, color: 'text-cyan-400' },
|
|
39
|
+
{ label: '24H_TRADES', value: `${trades}`, color: accentColor ? '' : 'text-cyan-400', colorStyle: accentColor ? { color: accentColor } : undefined },
|
|
37
40
|
{ label: 'BUY/SELL', value: `${buys}/${sells}`, color: 'text-white' },
|
|
38
41
|
];
|
|
39
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 mb-6", children: stats.map((stat) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-[10px] font-mono mb-1 tracking-wider", children: stat.label }), (0, jsx_runtime_1.jsx)("div", { className: `text-xl font-bold font-mono ${stat.color}`, children: stat.value }), stat.sub && ((0, jsx_runtime_1.jsx)("div", { className: `text-xs font-mono mt-0.5 ${stat.subColor || 'text-neutral-500'}`, children: stat.sub }))] }, stat.label))) }));
|
|
42
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 mb-6", children: stats.map((stat) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-[10px] font-mono mb-1 tracking-wider", children: stat.label }), (0, jsx_runtime_1.jsx)("div", { className: `text-xl font-bold font-mono ${stat.color}`, style: stat.colorStyle, children: stat.value }), stat.sub && ((0, jsx_runtime_1.jsx)("div", { className: `text-xs font-mono mt-0.5 ${stat.subColor || 'text-neutral-500'}`, style: stat.subStyle, children: stat.sub }))] }, stat.label))) }));
|
|
40
43
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmMCCTokenStatsProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmMCCTokenStats({ accentColor }?: MicrocosmMCCTokenStatsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,22 +5,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.MicrocosmMCCTokenStats = MicrocosmMCCTokenStats;
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
8
|
-
/* Inline SVG icons (16x16,
|
|
9
|
-
const IconUsers = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
10
|
-
const IconCircle = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
11
|
-
const IconPickaxe = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
12
|
-
const IconDollarSign = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
13
|
-
const IconCoin = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
14
|
-
function MicrocosmMCCTokenStats() {
|
|
8
|
+
/* Inline SVG icons (16x16, stroke-based) */
|
|
9
|
+
const IconUsers = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "7", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
|
|
10
|
+
const IconCircle = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 12h20" })] }));
|
|
11
|
+
const IconPickaxe = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M14.531 12.469 6.619 20.38a1 1 0 1 1-3-3l7.912-7.912" }), (0, jsx_runtime_1.jsx)("path", { d: "M15.686 4.314A12.5 12.5 0 0 0 5.461 2.958l-.834 2.22a5.25 5.25 0 0 0 4.626 7.065l.172-.003a5.25 5.25 0 0 0 5.022-3.89l.39-1.507a12.5 12.5 0 0 0 .849-2.53Z" })] }));
|
|
12
|
+
const IconDollarSign = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("line", { x1: "12", x2: "12", y1: "2", y2: "22" }), (0, jsx_runtime_1.jsx)("path", { d: "M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" })] }));
|
|
13
|
+
const IconCoin = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "8", cy: "8", r: "6" }), (0, jsx_runtime_1.jsx)("path", { d: "M18.09 10.37A6 6 0 1 1 10.34 18" }), (0, jsx_runtime_1.jsx)("path", { d: "M7 6h1v4" })] }));
|
|
14
|
+
function MicrocosmMCCTokenStats({ accentColor } = {}) {
|
|
15
15
|
const { data, loading } = (0, auth_react_1.useMCCStats)();
|
|
16
|
+
const ac = accentColor || '#22d3ee';
|
|
16
17
|
const stats = [
|
|
17
18
|
{ label: 'holders', value: data?.holders_count, format: (v) => v.toLocaleString(), icon: IconUsers },
|
|
18
19
|
{ label: 'circulating', value: data?.circulating_supply, format: (v) => `${(v / 1e6).toFixed(2)}M`, icon: IconCircle },
|
|
19
20
|
{ label: 'total_mining_tx', value: data?.total_mining_count, format: (v) => v.toLocaleString(), icon: IconPickaxe },
|
|
20
21
|
{ label: 'total_mining_usdc', value: data?.total_mining_usdc, format: (v) => `$${(v / 1e6).toFixed(2)}M`, icon: IconDollarSign },
|
|
21
22
|
];
|
|
22
|
-
|
|
23
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
24
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-4", children: [(0, jsx_runtime_1.jsx)(IconCoin, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "MCC_STATS" })] }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 gap-3", children: stats.map((s) => {
|
|
23
26
|
const Icon = s.icon;
|
|
24
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold font-mono text-white", children: s.value != null ? s.format(s.value) : '--' })] }, s.label));
|
|
27
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold font-mono text-white", children: s.value != null ? s.format(s.value) : '--' })] }, s.label));
|
|
25
28
|
}) }))] }) }));
|
|
26
29
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmMCDStatsProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmMCDStats({ accentColor }?: MicrocosmMCDStatsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,22 +5,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.MicrocosmMCDStats = MicrocosmMCDStats;
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
8
|
-
/* Inline SVG icons (16x16,
|
|
9
|
-
const IconUsers = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
10
|
-
const IconVault = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
11
|
-
const IconArrowDown = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
12
|
-
const IconWallet = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
13
|
-
const IconBanknote = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
14
|
-
function MicrocosmMCDStats() {
|
|
8
|
+
/* Inline SVG icons (16x16, stroke-based) */
|
|
9
|
+
const IconUsers = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "7", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
|
|
10
|
+
const IconVault = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 8v1" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 15v1" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 12h1" }), (0, jsx_runtime_1.jsx)("path", { d: "M15 12h1" })] }));
|
|
11
|
+
const IconArrowDown = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M12 5v14" }), (0, jsx_runtime_1.jsx)("path", { d: "m19 12-7 7-7-7" })] }));
|
|
12
|
+
const IconWallet = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M21 12V7H5a2 2 0 0 1 0-4h14v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 5v14a2 2 0 0 0 2 2h16v-5" }), (0, jsx_runtime_1.jsx)("path", { d: "M18 12a2 2 0 0 0 0 4h4v-4Z" })] }));
|
|
13
|
+
const IconBanknote = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("rect", { width: "20", height: "12", x: "2", y: "6", rx: "2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M6 12h.01M18 12h.01" })] }));
|
|
14
|
+
function MicrocosmMCDStats({ accentColor } = {}) {
|
|
15
15
|
const { data, loading } = (0, auth_react_1.useMCDStats)();
|
|
16
|
+
const ac = accentColor || '#22d3ee';
|
|
16
17
|
const stats = [
|
|
17
|
-
{ label: 'holders', value: data?.holders_count, format: (v) => v.toLocaleString(), icon: IconUsers },
|
|
18
|
-
{ label: 'active_vaults', value: data?.active_vaults, format: (v) => v.toLocaleString(), icon: IconVault },
|
|
18
|
+
{ label: 'holders', value: data?.holders_count ?? data?.holder_count, format: (v) => v.toLocaleString(), icon: IconUsers },
|
|
19
|
+
{ label: 'active_vaults', value: data?.total_vaults ?? data?.active_vaults, format: (v) => v.toLocaleString(), icon: IconVault },
|
|
19
20
|
{ label: 'daily_distribution', value: data?.daily_distribution, format: (v) => v > 0 ? v.toLocaleString('en-US', { maximumFractionDigits: 2 }) : '0', icon: IconArrowDown },
|
|
20
21
|
{ label: 'total_vault_balance', value: data?.total_vault_balance, format: (v) => v > 0 ? `${(v / 1e6).toFixed(2)}M` : '0', icon: IconWallet },
|
|
21
22
|
];
|
|
22
|
-
|
|
23
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
24
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-4", children: [(0, jsx_runtime_1.jsx)(IconBanknote, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "MCD_STATS" })] }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 gap-3", children: stats.map((s) => {
|
|
23
26
|
const Icon = s.icon;
|
|
24
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold font-mono text-white", children: s.value != null ? s.format(s.value) : '--' })] }, s.label));
|
|
27
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(Icon, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold font-mono text-white", children: s.value != null ? s.format(s.value) : '--' })] }, s.label));
|
|
25
28
|
}) }))] }) }));
|
|
26
29
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmMiningWeightProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmMiningWeight({ accentColor }?: MicrocosmMiningWeightProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -24,11 +24,11 @@ const RANK_COLORS = {
|
|
|
24
24
|
Warden: 'text-cyan-300',
|
|
25
25
|
Admiral: 'text-cyan-300',
|
|
26
26
|
};
|
|
27
|
-
/* Inline SVG icons (16x16,
|
|
28
|
-
const IconShield = () => ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
29
|
-
const IconTree = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
30
|
-
const IconCalendar = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
31
|
-
const IconPickaxe = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
27
|
+
/* Inline SVG icons (16x16, stroke-based) */
|
|
28
|
+
const IconShield = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }) }));
|
|
29
|
+
const IconTree = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M12 22v-7" }), (0, jsx_runtime_1.jsx)("path", { d: "M7 15h10" }), (0, jsx_runtime_1.jsx)("path", { d: "m12 2-5.5 9h11Z" }), (0, jsx_runtime_1.jsx)("path", { d: "m12 7-4 6h8Z" })] }));
|
|
30
|
+
const IconCalendar = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M8 2v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 2v4" }), (0, jsx_runtime_1.jsx)("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 10h18" })] }));
|
|
31
|
+
const IconPickaxe = ({ stroke = '#22d3ee' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M14.531 12.469 6.619 20.38a1 1 0 1 1-3-3l7.912-7.912" }), (0, jsx_runtime_1.jsx)("path", { d: "M15.686 4.314A12.5 12.5 0 0 0 5.461 2.958l-.834 2.22a5.25 5.25 0 0 0 4.626 7.065l.172-.003a5.25 5.25 0 0 0 5.022-3.89l.39-1.507a12.5 12.5 0 0 0 .849-2.53Z" })] }));
|
|
32
32
|
function getCompanionYield(rank) {
|
|
33
33
|
if (!rank)
|
|
34
34
|
return [];
|
|
@@ -43,16 +43,19 @@ function getCompanionYield(rank) {
|
|
|
43
43
|
{ label: '\u9886\u5730\u91d1\u5e93', share: '30%', type: 'MCD' },
|
|
44
44
|
];
|
|
45
45
|
}
|
|
46
|
-
function MicrocosmMiningWeight() {
|
|
46
|
+
function MicrocosmMiningWeight({ accentColor } = {}) {
|
|
47
47
|
const { data, loading: loadingLevel } = (0, auth_react_1.useUserLevel)();
|
|
48
48
|
const { data: techBonus, loading: loadingTech } = (0, auth_react_1.useTechTreeBonus)();
|
|
49
49
|
const { data: miningStats, loading: loadingMining } = (0, auth_react_1.useMiningStats)();
|
|
50
50
|
const loading = loadingLevel || loadingTech || loadingMining;
|
|
51
|
+
const ac = accentColor || '#22d3ee';
|
|
51
52
|
const rank = data?.level ?? null;
|
|
52
53
|
const miningDays = data?.upgrade_progress?.current_days ?? miningStats?.active_days_30d ?? 0;
|
|
53
54
|
const companionYield = getCompanionYield(rank);
|
|
54
55
|
// Tech tree discount
|
|
55
56
|
const bonusMultiplier = techBonus?.bonus_multiplier ?? 0;
|
|
56
57
|
const discountPct = bonusMultiplier > 0 ? `-${(bonusMultiplier * 100).toFixed(0)}%` : '0%';
|
|
57
|
-
|
|
58
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
59
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
60
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-4", children: [(0, jsx_runtime_1.jsx)(IconPickaxe, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "MINING_WEIGHT" })] }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-12", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-3 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(IconShield, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "level" })] }), (0, jsx_runtime_1.jsx)("div", { className: `text-sm font-bold font-mono ${accentColor ? '' : (RANK_COLORS[rank ?? ''] ?? 'text-neutral-500')}`, style: accentColor ? { color: accentColor } : undefined, children: rank ? RANK_LABELS[rank] ?? rank : 'N/A' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(IconTree, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "tech_tree" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-bold font-mono text-white", children: discountPct }), (0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-500 font-mono", children: "mining discount" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 mb-1", children: [(0, jsx_runtime_1.jsx)(IconCalendar, { stroke: ac }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "mining_days" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm font-bold font-mono text-white", children: miningDays }), (0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-500 font-mono", children: "cumulative" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-xs font-mono tracking-wider mb-3", children: "companion_yield" }), (0, jsx_runtime_1.jsx)("p", { className: "text-[10px] text-neutral-500 font-mono mb-3", children: "Each mining produces companion yield, auto-injected into territory ecosystem" }), (0, jsx_runtime_1.jsx)("div", { className: "space-y-2", children: companionYield.map((row) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between px-2 py-1.5 bg-neutral-900 rounded hover:bg-neutral-700 transition-colors", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs font-mono text-neutral-300", children: row.label }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs font-mono font-bold text-white", children: row.share }), (0, jsx_runtime_1.jsx)("span", { className: accentColor ? 'text-[10px] font-mono px-1.5 py-0.5 rounded' : 'text-[10px] font-mono px-1.5 py-0.5 rounded bg-cyan-400/20 text-cyan-400', style: accentColor ? { backgroundColor: `${accentColor}33`, color: accentColor } : undefined, children: row.type })] })] }, row.label))) }), rank && (rank === auth_core_1.UserRank.RECRUIT || rank === auth_core_1.UserRank.PROSPECT) && ((0, jsx_runtime_1.jsx)("div", { className: "mt-3 text-[10px] text-neutral-500 font-mono border-t border-neutral-700 pt-2", children: "Upgrade to Miner to unlock Magistrate + Station Vault distribution" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-[10px] text-neutral-500 font-mono space-y-1", children: [(0, jsx_runtime_1.jsxs)("div", { children: ['\u94f8\u9020\u4ef7\u683c', " = ", '\u5e02\u573a\u4ef7', " x 2 (", '\u7528\u6237\u83b7\u5f97', " 100% MCC)"] }), (0, jsx_runtime_1.jsxs)("div", { children: ['\u4f34\u751f\u77ff\u4e0e\u7528\u6237\u6316\u77ff\u91cf', " 1:1 ", '\u540c\u6b65\u4ea7\u51fa'] })] })] }))] }) }));
|
|
58
61
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmMintingStatsProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmMintingStats({ accentColor }?: MicrocosmMintingStatsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.MicrocosmMintingStats = MicrocosmMintingStats;
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
8
|
-
function MicrocosmMintingStats() {
|
|
8
|
+
function MicrocosmMintingStats({ accentColor } = {}) {
|
|
9
9
|
const { data: mccStats, loading } = (0, auth_react_1.useMCCStats)();
|
|
10
10
|
const { data: marketData } = (0, auth_react_1.useMarketData)();
|
|
11
11
|
const s = mccStats;
|
|
@@ -15,9 +15,12 @@ function MicrocosmMintingStats() {
|
|
|
15
15
|
const nextHalving = s?.next_halving_at ?? 100000000;
|
|
16
16
|
const price = marketData?.price_usd ?? 0;
|
|
17
17
|
const fmt = (n) => n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
18
|
-
|
|
18
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
19
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
20
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsx)("div", { className: "p-6", children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: accentColor ? '' : 'text-cyan-400', style: accentColor ? { color: accentColor } : undefined, children: "\u26A1" }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "MINTING_STATS" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 font-mono tracking-wider mb-1", children: "total_minted" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xl font-bold font-mono text-white", children: [totalMinted > 0 ? fmt(totalMinted) : '0', " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 font-mono tracking-wider mb-1", children: "mining_price" }), (0, jsx_runtime_1.jsxs)("div", { className: accentColor ? 'text-xl font-bold font-mono' : 'text-xl font-bold font-mono text-cyan-400', style: accentColor ? { color: accentColor } : undefined, children: ["$", price > 0 ? (price * 2).toFixed(4) : '--'] }), (0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-500 font-mono", children: "market \u00D7 2" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2 text-sm font-mono", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "next_halving" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white", children: [nextHalving > totalMinted
|
|
19
21
|
? (nextHalving - totalMinted).toLocaleString('en-US', { maximumFractionDigits: 0 })
|
|
20
|
-
: 'N/A', " MCC"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-700 rounded-full h-2", children: (0, jsx_runtime_1.jsx)("div", { className:
|
|
22
|
+
: 'N/A', " MCC"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-700 rounded-full h-2", children: (0, jsx_runtime_1.jsx)("div", { className: accentColor ? 'h-2 rounded-full transition-all' : 'bg-cyan-400 h-2 rounded-full transition-all', style: {
|
|
21
23
|
width: nextHalving > 0 ? `${Math.min((totalMinted % nextHalving) / nextHalving * 100, 100)}%` : '0%',
|
|
24
|
+
...(accentColor ? { backgroundColor: accentColor } : {}),
|
|
22
25
|
} }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mt-2 text-xs text-neutral-500 font-mono", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["phase: ", currentStage, " | rate: ", miningRate > 0 ? `${miningRate}:1` : '--'] }), (0, jsx_runtime_1.jsxs)("span", { children: ["threshold: ", (nextHalving / 1e6).toFixed(0), "M"] })] })] })] })) }) }));
|
|
23
26
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface MicrocosmMyMiningProps {
|
|
2
2
|
detailsPath?: string;
|
|
3
3
|
onNavigate?: (path: string) => void;
|
|
4
|
+
accentColor?: string;
|
|
4
5
|
}
|
|
5
|
-
export declare function MicrocosmMyMining({ detailsPath, onNavigate }: MicrocosmMyMiningProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function MicrocosmMyMining({ detailsPath, onNavigate, accentColor }: MicrocosmMyMiningProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.MicrocosmMyMining = MicrocosmMyMining;
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
8
|
-
function MicrocosmMyMining({ detailsPath, onNavigate }) {
|
|
8
|
+
function MicrocosmMyMining({ detailsPath, onNavigate, accentColor }) {
|
|
9
9
|
const { data, loading } = (0, auth_react_1.useMiningStats)();
|
|
10
10
|
const fmt = (v) => v.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
11
11
|
const formatDateTime = (iso) => {
|
|
@@ -26,5 +26,7 @@ function MicrocosmMyMining({ detailsPath, onNavigate }) {
|
|
|
26
26
|
if (onNavigate && detailsPath)
|
|
27
27
|
onNavigate(detailsPath);
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
const spinnerBorderColor = accentColor ? { borderColor: accentColor, borderTopColor: 'transparent' } : undefined;
|
|
30
|
+
const spinnerClass = accentColor ? 'inline-block w-5 h-5 border-2 rounded-full animate-spin' : 'inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin';
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg h-full hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider", children: "MY_MINING" }), detailsPath && ((0, jsx_runtime_1.jsx)("button", { onClick: handleDetailsClick, className: accentColor ? 'text-xs text-neutral-500 font-mono' : 'text-xs text-neutral-500 hover:text-cyan-400 font-mono', style: accentColor ? { '--hover-color': accentColor } : undefined, children: "details >" }))] }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)("span", { className: spinnerClass, style: spinnerBorderColor }) })) : !data || (data.mining_count ?? 0) === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500 font-mono text-sm", children: "no mining records" })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 gap-3", children: items.map((s) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-neutral-400 font-mono tracking-wider", children: s.label }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold font-mono text-white", children: s.value })] }, s.label))) }))] }) }));
|
|
30
32
|
}
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface MicrocosmPriceChartProps {
|
|
2
|
+
accentColor?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function MicrocosmPriceChart({ accentColor }?: MicrocosmPriceChartProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,9 +12,11 @@ const timeRanges = [
|
|
|
12
12
|
{ label: '7D', value: '7D' },
|
|
13
13
|
{ label: '30D', value: '30D' },
|
|
14
14
|
];
|
|
15
|
-
function MicrocosmPriceChart() {
|
|
15
|
+
function MicrocosmPriceChart({ accentColor } = {}) {
|
|
16
16
|
const [range, setRange] = (0, react_1.useState)('7D');
|
|
17
17
|
const { data, loading } = (0, auth_react_1.usePriceHistory)(range);
|
|
18
|
+
const gradientId = (0, react_1.useId)().replace(/:/g, '_') + '_mcPriceGradient';
|
|
19
|
+
const ac = accentColor || '#22d3ee';
|
|
18
20
|
const raw = data;
|
|
19
21
|
const items = Array.isArray(raw) ? raw : raw?.records ?? [];
|
|
20
22
|
const chartData = items.map((item) => ({
|
|
@@ -33,12 +35,12 @@ function MicrocosmPriceChart() {
|
|
|
33
35
|
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
34
36
|
};
|
|
35
37
|
return ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg overflow-hidden hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between mb-4", children: (0, jsx_runtime_1.jsx)("div", { className: "flex gap-1 bg-black p-0.5 rounded", children: timeRanges.map((tr) => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setRange(tr.value), className: `px-2.5 py-1 text-[10px] font-mono font-bold rounded transition-colors ${range === tr.value
|
|
36
|
-
? 'bg-cyan-700 text-white'
|
|
37
|
-
: 'text-neutral-500 hover:text-neutral-300'}`, children: tr.label }, tr.value))) }) }), (0, jsx_runtime_1.jsx)("div", { className: "h-[360px]", children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "h-full bg-neutral-800 rounded animate-pulse" })) : chartData.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "h-full flex items-center justify-center text-neutral-500 font-mono text-sm", children: "No price data available" })) : ((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: 5, left: -15, bottom: 0 }, children: [(0, jsx_runtime_1.jsx)("defs", { children: (0, jsx_runtime_1.jsxs)("linearGradient", { id:
|
|
38
|
+
? (accentColor ? 'text-white' : 'bg-cyan-700 text-white')
|
|
39
|
+
: 'text-neutral-500 hover:text-neutral-300'}`, style: range === tr.value && accentColor ? { backgroundColor: accentColor, opacity: 0.8 } : undefined, children: tr.label }, tr.value))) }) }), (0, jsx_runtime_1.jsx)("div", { className: "h-[360px]", children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "h-full bg-neutral-800 rounded animate-pulse" })) : chartData.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "h-full flex items-center justify-center text-neutral-500 font-mono text-sm", children: "No price data available" })) : ((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: 5, left: -15, bottom: 0 }, children: [(0, jsx_runtime_1.jsx)("defs", { children: (0, jsx_runtime_1.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [(0, jsx_runtime_1.jsx)("stop", { offset: "5%", stopColor: ac, stopOpacity: 0.3 }), (0, jsx_runtime_1.jsx)("stop", { offset: "95%", stopColor: ac, stopOpacity: 0 })] }) }), (0, jsx_runtime_1.jsx)(recharts_1.CartesianGrid, { vertical: false, strokeDasharray: "3 3", stroke: "#404040" }), (0, jsx_runtime_1.jsx)(recharts_1.XAxis, { dataKey: "time", tick: { fill: '#737373', fontSize: 10, fontFamily: 'monospace' }, tickLine: false, axisLine: false, tickFormatter: formatTime }), (0, jsx_runtime_1.jsx)(recharts_1.YAxis, { tick: { fill: '#737373', fontSize: 10, fontFamily: 'monospace' }, tickLine: false, axisLine: false, tickFormatter: (v) => `$${v.toFixed(3)}`, domain: [minPrice, maxPrice] }), (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { contentStyle: {
|
|
38
40
|
backgroundColor: '#171717',
|
|
39
41
|
border: '1px solid #404040',
|
|
40
42
|
borderRadius: '6px',
|
|
41
43
|
fontFamily: 'monospace',
|
|
42
44
|
fontSize: '11px',
|
|
43
|
-
}, labelFormatter: (ts) => new Date(ts).toLocaleString(), formatter: (value) => [`$${Number(value).toFixed(4)}`, 'Price'] }), (0, jsx_runtime_1.jsx)(recharts_1.Area, { type: "monotone", dataKey: "price", stroke:
|
|
45
|
+
}, labelFormatter: (ts) => new Date(ts).toLocaleString(), formatter: (value) => [`$${Number(value).toFixed(4)}`, 'Price'] }), (0, jsx_runtime_1.jsx)(recharts_1.Area, { type: "monotone", dataKey: "price", stroke: ac, strokeWidth: 2, fill: `url(#${gradientId})` })] }) })) })] }) }));
|
|
44
46
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface MicrocosmQuickActionsProps {
|
|
2
2
|
basePath?: string;
|
|
3
3
|
onNavigate?: (path: string) => void;
|
|
4
|
+
accentColor?: string;
|
|
4
5
|
}
|
|
5
|
-
export declare function MicrocosmQuickActions({ basePath, onNavigate }: MicrocosmQuickActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function MicrocosmQuickActions({ basePath, onNavigate, accentColor }: MicrocosmQuickActionsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,46 +8,61 @@ const MCC_MINT = 'MCCn6eqiTGzaiPKECg3viPmkdkS9YmkguqKvRcTxCsb';
|
|
|
8
8
|
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
9
9
|
const POOL_ID = '4AiaTd9bAWf3u8ScZWhXadJF1roc8bJKEKvaDudKacZd';
|
|
10
10
|
/* Inline SVG icons matching lucide-react style (20x20, stroke-based) */
|
|
11
|
-
const IconDroplets = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
11
|
+
const IconDroplets = ({ stroke = 'currentColor' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M7 16.3c2.2 0 4-1.83 4-4.05 0-1.16-.57-2.26-1.71-3.19S7.29 6.75 7 5.3c-.29 1.45-1.14 2.84-2.29 3.76S3 11.1 3 12.25c0 2.22 1.8 4.05 4 4.05z" }), (0, jsx_runtime_1.jsx)("path", { d: "M12.56 6.6A10.97 10.97 0 0 0 14 3.02c.5 2.5 2 4.9 4 6.5s3 3.5 3 5.5a6.98 6.98 0 0 1-11.91 4.97" })] }));
|
|
12
12
|
const IconRepeat = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "m17 1 4 4-4 4" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 11V9a4 4 0 0 1 4-4h14" }), (0, jsx_runtime_1.jsx)("path", { d: "m7 23-4-4 4-4" }), (0, jsx_runtime_1.jsx)("path", { d: "M21 13v2a4 4 0 0 1-4 4H3" })] }));
|
|
13
|
-
const IconEye = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
13
|
+
const IconEye = ({ stroke = 'currentColor' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "3" })] }));
|
|
14
14
|
const IconBarChart3 = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M3 3v18h18" }), (0, jsx_runtime_1.jsx)("path", { d: "M18 17V9" }), (0, jsx_runtime_1.jsx)("path", { d: "M13 17V5" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 17v-3" })] }));
|
|
15
|
-
const IconLineChart = () => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
15
|
+
const IconLineChart = ({ stroke = 'currentColor' }) => ((0, jsx_runtime_1.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: stroke, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M3 3v18h18" }), (0, jsx_runtime_1.jsx)("path", { d: "m19 9-5 5-4-4-3 3" })] }));
|
|
16
|
+
function buildExchanges(accentColor) {
|
|
17
|
+
const accentClass = accentColor ? 'border-neutral-700 hover:bg-neutral-800' : 'text-cyan-300 border-cyan-400/30 hover:bg-cyan-950/30';
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
label: 'Raydium',
|
|
21
|
+
href: `https://raydium.io/swap/?inputMint=${MCC_MINT}&outputMint=${USDC_MINT}`,
|
|
22
|
+
color: accentClass,
|
|
23
|
+
colorStyle: accentColor ? { color: accentColor } : undefined,
|
|
24
|
+
icon: IconDroplets,
|
|
25
|
+
iconAccent: true,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Jupiter',
|
|
29
|
+
href: `https://jup.ag/swap/USDT-${MCC_MINT}`,
|
|
30
|
+
color: 'text-white border-neutral-700 hover:bg-neutral-800',
|
|
31
|
+
colorStyle: undefined,
|
|
32
|
+
icon: IconRepeat,
|
|
33
|
+
iconAccent: false,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: 'BirdEye',
|
|
37
|
+
href: `https://birdeye.so/token/${MCC_MINT}?chain=solana`,
|
|
38
|
+
color: accentClass,
|
|
39
|
+
colorStyle: accentColor ? { color: accentColor } : undefined,
|
|
40
|
+
icon: IconEye,
|
|
41
|
+
iconAccent: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: 'GMGN',
|
|
45
|
+
href: `https://gmgn.ai/sol/token/${MCC_MINT}`,
|
|
46
|
+
color: 'text-white border-neutral-700 hover:bg-neutral-800',
|
|
47
|
+
colorStyle: undefined,
|
|
48
|
+
icon: IconBarChart3,
|
|
49
|
+
iconAccent: false,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
label: 'DexScreener',
|
|
53
|
+
href: `https://dexscreener.com/solana/${POOL_ID}`,
|
|
54
|
+
color: accentClass,
|
|
55
|
+
colorStyle: accentColor ? { color: accentColor } : undefined,
|
|
56
|
+
icon: IconLineChart,
|
|
57
|
+
iconAccent: true,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
function MicrocosmQuickActions({ basePath = '', onNavigate, accentColor }) {
|
|
62
|
+
const exchanges = buildExchanges(accentColor);
|
|
49
63
|
return ((0, jsx_runtime_1.jsx)("div", { className: "mb-6", children: (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 lg:grid-cols-5 gap-3", children: exchanges.map((ex) => {
|
|
50
64
|
const Icon = ex.icon;
|
|
51
|
-
|
|
65
|
+
const iconStroke = ex.iconAccent && accentColor ? accentColor : undefined;
|
|
66
|
+
return ((0, jsx_runtime_1.jsx)("a", { href: ex.href, target: "_blank", rel: "noopener noreferrer", children: (0, jsx_runtime_1.jsxs)("div", { className: `bg-neutral-900 border ${ex.color} rounded-lg p-4 flex items-center gap-3 cursor-pointer active:scale-[0.98] transition-colors`, style: ex.colorStyle, children: [(0, jsx_runtime_1.jsx)(Icon, { stroke: iconStroke }), (0, jsx_runtime_1.jsx)("span", { className: "font-mono text-sm font-bold tracking-wider", children: ex.label })] }) }, ex.label));
|
|
52
67
|
}) }) }));
|
|
53
68
|
}
|
|
@@ -7,162 +7,135 @@ 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
9
|
/* ------------------------------------------------------------------ */
|
|
10
|
-
/* Inline SVG Icons (
|
|
10
|
+
/* Inline SVG Icons (24x24 viewBox, stroke 2, round caps) */
|
|
11
11
|
/* ------------------------------------------------------------------ */
|
|
12
12
|
const IconBuilding2 = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z" }), (0, jsx_runtime_1.jsx)("path", { d: "M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2" }), (0, jsx_runtime_1.jsx)("path", { d: "M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2" }), (0, jsx_runtime_1.jsx)("path", { d: "M10 6h4" }), (0, jsx_runtime_1.jsx)("path", { d: "M10 10h4" }), (0, jsx_runtime_1.jsx)("path", { d: "M10 14h4" }), (0, jsx_runtime_1.jsx)("path", { d: "M10 18h4" })] }));
|
|
13
13
|
const IconGrid3x3 = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 9h18" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 15h18" }), (0, jsx_runtime_1.jsx)("path", { d: "M9 3v18" }), (0, jsx_runtime_1.jsx)("path", { d: "M15 3v18" })] }));
|
|
14
14
|
const IconMap = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z" }), (0, jsx_runtime_1.jsx)("path", { d: "M15 5.764v15" }), (0, jsx_runtime_1.jsx)("path", { d: "M9 3.236v15" })] }));
|
|
15
15
|
const IconGlobe = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 12h20" })] }));
|
|
16
|
-
const
|
|
16
|
+
const IconUsers = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "7", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.87" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] }));
|
|
17
|
+
const IconVault = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 8v8" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 12h8" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 10h2" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 14h2" }), (0, jsx_runtime_1.jsx)("path", { d: "M20 10h2" }), (0, jsx_runtime_1.jsx)("path", { d: "M20 14h2" })] }));
|
|
18
|
+
const IconZap = ({ className = '' }) => ((0, jsx_runtime_1.jsx)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M13 2 3 14h9l-1 8 10-12h-9l1-8z" }) }));
|
|
17
19
|
const IconSearch = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "11", cy: "11", r: "8" }), (0, jsx_runtime_1.jsx)("path", { d: "m21 21-4.3-4.3" })] }));
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
20
|
+
const IconArrowLeft = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "m12 19-7-7 7-7" }), (0, jsx_runtime_1.jsx)("path", { d: "M19 12H5" })] }));
|
|
21
|
+
const IconShield = ({ className = '' }) => ((0, jsx_runtime_1.jsx)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C8.5 20.5 5 18 5 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C15.5 3.8 18 5 20 5a1 1 0 0 1 1 1z" }) }));
|
|
22
|
+
const IconCalendar = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M8 2v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 2v4" }), (0, jsx_runtime_1.jsx)("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 10h18" })] }));
|
|
23
|
+
const IconImage = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "9", r: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })] }));
|
|
24
|
+
const IconSettings = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "3" })] }));
|
|
25
|
+
const IconEdit3 = ({ className = '' }) => ((0, jsx_runtime_1.jsxs)("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [(0, jsx_runtime_1.jsx)("path", { d: "M12 20h9" }), (0, jsx_runtime_1.jsx)("path", { d: "M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.855z" })] }));
|
|
23
26
|
/* ------------------------------------------------------------------ */
|
|
24
27
|
/* Helpers */
|
|
25
28
|
/* ------------------------------------------------------------------ */
|
|
26
29
|
const fmt = (n) => n.toLocaleString('en-US');
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return `${address.slice(0, start)}...${address.slice(-end)}`;
|
|
33
|
-
}
|
|
34
|
-
const getNftTypeIcon = (type) => {
|
|
35
|
-
switch (type?.toLowerCase()) {
|
|
36
|
-
case 'station': return (0, jsx_runtime_1.jsx)(IconBuilding2, { className: "w-5 h-5" });
|
|
37
|
-
case 'matrix': return (0, jsx_runtime_1.jsx)(IconGrid3x3, { className: "w-5 h-5" });
|
|
38
|
-
case 'sector': return (0, jsx_runtime_1.jsx)(IconMap, { className: "w-5 h-5" });
|
|
39
|
-
case 'system': return (0, jsx_runtime_1.jsx)(IconGlobe, { className: "w-5 h-5" });
|
|
40
|
-
default: return (0, jsx_runtime_1.jsx)(IconImage, { className: "w-5 h-5" });
|
|
41
|
-
}
|
|
30
|
+
const TECH_BONUS = {
|
|
31
|
+
station: 10,
|
|
32
|
+
matrix: 20,
|
|
33
|
+
sector: 30,
|
|
34
|
+
system: 40,
|
|
42
35
|
};
|
|
43
|
-
const
|
|
36
|
+
const getTypeIcon = (type, className = 'w-5 h-5') => {
|
|
44
37
|
switch (type?.toLowerCase()) {
|
|
45
|
-
case 'station': return
|
|
46
|
-
case 'matrix': return
|
|
47
|
-
case 'sector': return
|
|
48
|
-
case 'system': return
|
|
49
|
-
default: return
|
|
38
|
+
case 'station': return (0, jsx_runtime_1.jsx)(IconBuilding2, { className: className });
|
|
39
|
+
case 'matrix': return (0, jsx_runtime_1.jsx)(IconGrid3x3, { className: className });
|
|
40
|
+
case 'sector': return (0, jsx_runtime_1.jsx)(IconMap, { className: className });
|
|
41
|
+
case 'system': return (0, jsx_runtime_1.jsx)(IconGlobe, { className: className });
|
|
42
|
+
default: return (0, jsx_runtime_1.jsx)(IconSettings, { className: className });
|
|
50
43
|
}
|
|
51
44
|
};
|
|
52
|
-
const
|
|
45
|
+
const getTypeBadgeColor = (type) => {
|
|
53
46
|
switch (type?.toLowerCase()) {
|
|
54
|
-
case 'station': return '
|
|
55
|
-
case 'matrix': return '
|
|
56
|
-
case 'sector': return '
|
|
57
|
-
case 'system': return '
|
|
58
|
-
default: return
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
const getStatIcon = (label) => {
|
|
62
|
-
switch (label) {
|
|
63
|
-
case 'Station': return (0, jsx_runtime_1.jsx)(IconBuilding2, { className: "w-4 h-4 text-neutral-400" });
|
|
64
|
-
case 'Matrix': return (0, jsx_runtime_1.jsx)(IconGrid3x3, { className: "w-4 h-4 text-cyan-300" });
|
|
65
|
-
case 'Sector': return (0, jsx_runtime_1.jsx)(IconMap, { className: "w-4 h-4 text-cyan-300" });
|
|
66
|
-
case 'Total Minted': return (0, jsx_runtime_1.jsx)(IconImage, { className: "w-4 h-4 text-cyan-400" });
|
|
67
|
-
default: return null;
|
|
47
|
+
case 'station': return 'border-cyan-400/40 text-cyan-400';
|
|
48
|
+
case 'matrix': return 'border-white/40 text-white';
|
|
49
|
+
case 'sector': return 'border-cyan-300/40 text-cyan-300';
|
|
50
|
+
case 'system': return 'border-cyan-200/40 text-cyan-200';
|
|
51
|
+
default: return 'border-neutral-600 text-neutral-400';
|
|
68
52
|
}
|
|
69
53
|
};
|
|
54
|
+
const UNIT_TYPE_LABELS = [
|
|
55
|
+
{ key: 'all', label: 'All' },
|
|
56
|
+
{ key: 'station', label: 'Station' },
|
|
57
|
+
{ key: 'matrix', label: 'Matrix' },
|
|
58
|
+
{ key: 'sector', label: 'Sector' },
|
|
59
|
+
{ key: 'system', label: 'System' },
|
|
60
|
+
];
|
|
70
61
|
/* ------------------------------------------------------------------ */
|
|
71
|
-
/* Spinner
|
|
62
|
+
/* Spinner / Skeleton */
|
|
72
63
|
/* ------------------------------------------------------------------ */
|
|
73
64
|
function Spinner() {
|
|
74
65
|
return (0, jsx_runtime_1.jsx)("span", { className: "inline-block w-5 h-5 border-2 border-cyan-400 border-t-transparent rounded-full animate-spin" });
|
|
75
66
|
}
|
|
76
|
-
/* ------------------------------------------------------------------ */
|
|
77
|
-
/* Skeleton */
|
|
78
|
-
/* ------------------------------------------------------------------ */
|
|
79
67
|
function Skeleton({ className = '' }) {
|
|
80
68
|
return (0, jsx_runtime_1.jsx)("div", { className: `animate-pulse bg-neutral-800 rounded-lg ${className}` });
|
|
81
69
|
}
|
|
82
70
|
/* ------------------------------------------------------------------ */
|
|
83
|
-
/*
|
|
71
|
+
/* Territory Card (list view) */
|
|
84
72
|
/* ------------------------------------------------------------------ */
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
function TerritoryCard({ unit, onClick }) {
|
|
74
|
+
const unitType = (unit.unit_type || 'station');
|
|
75
|
+
const techBonus = TECH_BONUS[unitType.toLowerCase()] ?? 0;
|
|
76
|
+
const occupancy = unit.max_capacity && unit.max_capacity > 0
|
|
77
|
+
? Math.round(((unit.member_count ?? 0) / unit.max_capacity) * 100)
|
|
78
|
+
: 0;
|
|
79
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 cursor-pointer transition-colors overflow-hidden", onClick: onClick, children: [(0, jsx_runtime_1.jsx)("div", { className: "aspect-[4/3] bg-neutral-800 relative flex items-center justify-center overflow-hidden", children: unit.image_url ? ((0, jsx_runtime_1.jsx)("img", { src: unit.image_url, alt: unit.unit_name, className: "w-full h-full object-cover" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center text-neutral-600", children: [getTypeIcon(unitType, 'w-10 h-10'), (0, jsx_runtime_1.jsx)("span", { className: "text-xs mt-2 capitalize", children: unitType })] })) }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-2", style: { backgroundColor: '#0a0e14' }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-wrap", children: [(0, jsx_runtime_1.jsx)("span", { className: `border px-1.5 py-0.5 rounded text-xs capitalize ${getTypeBadgeColor(unitType)}`, children: unitType }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-yellow-400", children: [(0, jsx_runtime_1.jsx)(IconZap, { className: "w-3 h-3 inline-block -mt-0.5 mr-0.5" }), "+", techBonus, "%"] }), unit.short_id && ((0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-500 font-mono ml-auto", children: unit.short_id }))] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-white font-bold text-sm truncate", children: unit.unit_name }), unit.full_path && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-500 text-xs font-mono truncate", children: unit.full_path }))] }), unit.description && ((0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-xs line-clamp-2", children: unit.description })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4 pt-2 border-t border-neutral-700/50 text-xs text-neutral-400", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-3.5 h-3.5" }), fmt(unit.member_count ?? 0)] }), (0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconVault, { className: "w-3.5 h-3.5" }), fmt(Math.round(unit.vault_balance ?? 0)), " MCD"] }), (0, jsx_runtime_1.jsxs)("span", { className: "ml-auto", children: [occupancy, "%"] })] })] })] }));
|
|
89
80
|
}
|
|
90
81
|
/* ------------------------------------------------------------------ */
|
|
91
|
-
/*
|
|
82
|
+
/* Detail View */
|
|
92
83
|
/* ------------------------------------------------------------------ */
|
|
93
|
-
function
|
|
94
|
-
|
|
84
|
+
function TerritoryDetailView({ territoryId, territory, onBack }) {
|
|
85
|
+
const { data: detailedStats, loading: statsLoading } = (0, auth_react_1.useTerritoryDetailedStats)(territoryId);
|
|
86
|
+
const { data: members, loading: membersLoading } = (0, auth_react_1.useTerritoryMembers)(territoryId);
|
|
87
|
+
const stats = detailedStats;
|
|
88
|
+
const memberList = Array.isArray(members) ? members : [];
|
|
89
|
+
const unitType = (territory?.unit_type || 'station');
|
|
90
|
+
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;
|
|
94
|
+
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))) })] })) })] })] }));
|
|
95
98
|
}
|
|
96
99
|
/* ------------------------------------------------------------------ */
|
|
97
100
|
/* Main Component */
|
|
98
101
|
/* ------------------------------------------------------------------ */
|
|
99
102
|
function MicrocosmTerritoryPage({ basePath = '', onNavigate }) {
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const { data:
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
setSearchResults([data.data]);
|
|
130
|
-
}
|
|
131
|
-
else if (data && data.mint) {
|
|
132
|
-
setSearchResults([data]);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
setSearchResults([]);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
setSearchResults([]);
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
setSearching(false);
|
|
143
|
-
}
|
|
144
|
-
}, [api, searchQuery]);
|
|
145
|
-
const copyAddress = (0, react_1.useCallback)((address) => {
|
|
146
|
-
navigator.clipboard.writeText(address);
|
|
147
|
-
setCopiedAddress(address);
|
|
148
|
-
setTimeout(() => setCopiedAddress(null), 2000);
|
|
149
|
-
}, []);
|
|
150
|
-
const openNftDetail = (0, react_1.useCallback)((nft) => {
|
|
151
|
-
setSelectedNft(nft);
|
|
152
|
-
setShowNftDetail(true);
|
|
153
|
-
}, []);
|
|
154
|
-
/* -- Loading skeleton -- */
|
|
155
|
-
if (colLoading && nftsLoading) {
|
|
156
|
-
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.jsx)(Skeleton, { className: "h-8 w-48" }), (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-10 w-24" })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => ((0, jsx_runtime_1.jsx)(Skeleton, { className: "h-32" }, i))) }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [...Array(6)].map((_, i) => ((0, jsx_runtime_1.jsx)(Skeleton, { className: "h-64" }, i))) })] }));
|
|
103
|
+
const [selectedId, setSelectedId] = (0, react_1.useState)(null);
|
|
104
|
+
const [filterType, setFilterType] = (0, react_1.useState)('all');
|
|
105
|
+
const [searchTerm, setSearchTerm] = (0, react_1.useState)('');
|
|
106
|
+
const { data: summary, loading: summaryLoading } = (0, auth_react_1.useTerritorySummary)();
|
|
107
|
+
const { data: territories, loading: territoriesLoading } = (0, auth_react_1.useTerritories)(filterType === 'all' ? {} : { unitType: filterType });
|
|
108
|
+
const territoryList = Array.isArray(territories) ? territories : [];
|
|
109
|
+
const sum = summary;
|
|
110
|
+
// Client-side search filtering
|
|
111
|
+
const filteredTerritories = (0, react_1.useMemo)(() => {
|
|
112
|
+
if (!searchTerm.trim())
|
|
113
|
+
return territoryList;
|
|
114
|
+
const q = searchTerm.toLowerCase();
|
|
115
|
+
return territoryList.filter((t) => (t.unit_name && t.unit_name.toLowerCase().includes(q)) ||
|
|
116
|
+
(t.description && t.description.toLowerCase().includes(q)) ||
|
|
117
|
+
(t.short_id && t.short_id.toLowerCase().includes(q)) ||
|
|
118
|
+
(t.full_path && t.full_path.toLowerCase().includes(q)));
|
|
119
|
+
}, [territoryList, searchTerm]);
|
|
120
|
+
// Find selected territory object for detail view
|
|
121
|
+
const selectedTerritory = selectedId
|
|
122
|
+
? territoryList.find((t) => t.unit_id === selectedId)
|
|
123
|
+
: undefined;
|
|
124
|
+
/* -- Detail view -- */
|
|
125
|
+
if (selectedId) {
|
|
126
|
+
return ((0, jsx_runtime_1.jsx)(TerritoryDetailView, { territoryId: selectedId, territory: selectedTerritory, onBack: () => setSelectedId(null) }));
|
|
127
|
+
}
|
|
128
|
+
/* -- List view -- */
|
|
129
|
+
// Loading skeleton for initial load
|
|
130
|
+
if (summaryLoading && territoriesLoading) {
|
|
131
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between", children: (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-8 w-56" }) }), (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.jsx)(Skeleton, { className: "h-14" }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [...Array(6)].map((_, i) => (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-72" }, i)) })] }));
|
|
157
132
|
}
|
|
158
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", {
|
|
159
|
-
{ label: '
|
|
160
|
-
{ label: '
|
|
161
|
-
{ label: '
|
|
162
|
-
{ label: '
|
|
163
|
-
].map((s) => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg
|
|
164
|
-
? 'bg-
|
|
165
|
-
: 'text-neutral-
|
|
166
|
-
? 'bg-neutral-700 text-white'
|
|
167
|
-
: 'text-neutral-500 hover:text-neutral-300'}`, children: "All NFTs" })] }), (0, jsx_runtime_1.jsx)("div", { className: "mt-4", children: activeTab === 'my' ? (nftsLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => ((0, jsx_runtime_1.jsx)(Skeleton, { className: "h-64" }, i))) })) : nftList.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-8 text-center", children: [(0, jsx_runtime_1.jsx)(IconImage, { className: "w-12 h-12 mx-auto mb-4 text-neutral-600" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400", children: "No territory NFTs found" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Territory NFTs will appear here once assigned" })] }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4", children: nftList.map((nft) => ((0, jsx_runtime_1.jsx)(NFTCard, { nft: nft, onClick: () => openNftDetail(nft) }, nft.mint))) }))) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-8 text-center", children: [(0, jsx_runtime_1.jsx)(IconSearch, { className: "w-12 h-12 mx-auto mb-4 text-neutral-600" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400", children: "Use the search above to find specific NFTs" }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Enter a mint address to look up any territory NFT" })] }) })) })] }), (0, jsx_runtime_1.jsx)(Modal, { open: showNftDetail, onClose: () => setShowNftDetail(false), children: selectedNft && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-6 pb-0", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-lg font-semibold text-white", children: selectedNft.name }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "NFT Details" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-6 space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "aspect-square bg-neutral-800 rounded-lg flex items-center justify-center overflow-hidden", children: selectedNft.image ? ((0, jsx_runtime_1.jsx)("img", { src: selectedNft.image, alt: selectedNft.name, className: "w-full h-full object-cover" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center text-neutral-600", children: [getNftTypeIcon(selectedNft.nft_type), (0, jsx_runtime_1.jsx)("span", { className: "text-sm mt-2", children: "No Image" })] })) }), (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.jsx)("span", { className: "text-neutral-400 text-sm", children: "Type" }), (0, jsx_runtime_1.jsx)("span", { className: `text-xs px-2 py-0.5 rounded border ${getNftTypeColor(selectedNft.nft_type)}`, children: getNftTypeLabel(selectedNft.nft_type) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-sm", children: "Unit ID" }), (0, jsx_runtime_1.jsx)("span", { className: "text-white font-mono text-sm", children: selectedNft.unit_id })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-sm", children: "Symbol" }), (0, jsx_runtime_1.jsx)("span", { className: "text-white font-mono text-sm", children: selectedNft.symbol })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-sm", children: "Mint Address" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white font-mono text-xs", children: truncateAddress(selectedNft.mint, 8, 8) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => copyAddress(selectedNft.mint), className: "text-neutral-400 hover:text-white transition-colors", children: copiedAddress === selectedNft.mint ? ((0, jsx_runtime_1.jsx)(IconCheckCircle, { className: "w-4 h-4 text-white" })) : ((0, jsx_runtime_1.jsx)(IconCopy, { className: "w-4 h-4" })) })] })] }), selectedNft.owner && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-sm", children: "Owner" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white font-mono text-xs", children: truncateAddress(selectedNft.owner, 8, 8) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => copyAddress(selectedNft.owner), className: "text-neutral-400 hover:text-white transition-colors", children: copiedAddress === selectedNft.owner ? ((0, jsx_runtime_1.jsx)(IconCheckCircle, { className: "w-4 h-4 text-white" })) : ((0, jsx_runtime_1.jsx)(IconCopy, { className: "w-4 h-4" })) })] })] })), selectedNft.created_at && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-sm", children: "Created" }), (0, jsx_runtime_1.jsx)("span", { className: "text-white text-sm", children: new Date(selectedNft.created_at * 1000).toLocaleString() })] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 pt-2", children: [(0, jsx_runtime_1.jsxs)("button", { className: "flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm border border-neutral-700 rounded-lg text-neutral-300 hover:bg-neutral-800 transition-colors bg-transparent", onClick: () => window.open(`https://explorer.solana.com/address/${selectedNft.mint}`, '_blank'), children: [(0, jsx_runtime_1.jsx)(IconExternalLink, { className: "w-4 h-4" }), "Solana Explorer"] }), selectedNft.uri && ((0, jsx_runtime_1.jsxs)("button", { className: "flex-1 flex items-center justify-center gap-2 px-3 py-2 text-sm border border-neutral-700 rounded-lg text-neutral-300 hover:bg-neutral-800 transition-colors bg-transparent", onClick: () => window.open(selectedNft.uri, '_blank'), children: [(0, jsx_runtime_1.jsx)(IconExternalLink, { className: "w-4 h-4" }), "Metadata"] }))] })] })] })) })] }));
|
|
133
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-2xl font-bold text-white", children: "Territory Management" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-1", children: "Manage territories, view KPI and vault balances" })] }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [
|
|
134
|
+
{ label: 'Total Territories', value: sum?.total_stations ?? 0, icon: (0, jsx_runtime_1.jsx)(IconBuilding2, { className: "w-4 h-4 text-cyan-400" }), suffix: '' },
|
|
135
|
+
{ label: 'Total Members', value: sum?.total_members ?? 0, icon: (0, jsx_runtime_1.jsx)(IconUsers, { className: "w-4 h-4 text-neutral-400" }), suffix: '' },
|
|
136
|
+
{ label: 'Total Vault MCD', value: Math.round(sum?.total_vault_mcd ?? 0), icon: (0, jsx_runtime_1.jsx)(IconVault, { className: "w-4 h-4 text-neutral-400" }), suffix: ' MCD' },
|
|
137
|
+
{ label: 'Avg KPI', value: sum?.avg_kpi_score != null ? Math.round(sum.avg_kpi_score * 100) : 0, icon: (0, jsx_runtime_1.jsx)(IconEdit3, { className: "w-4 h-4 text-neutral-400" }), suffix: '%' },
|
|
138
|
+
].map((s) => ((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: [s.icon, (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-400", children: s.label })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-2xl font-bold text-white font-mono", children: summaryLoading ? (0, jsx_runtime_1.jsx)(Spinner, {}) : (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [fmt(s.value), s.suffix] }) })] }, s.label))) }), (0, jsx_runtime_1.jsx)("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 flex-col sm:flex-row gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [(0, jsx_runtime_1.jsx)(IconSearch, { className: "w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-neutral-500" }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Search territories...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "w-full pl-10 pr-3 py-2 bg-neutral-800 border border-neutral-700 rounded-lg text-white text-sm placeholder:text-neutral-500 outline-none focus:border-cyan-400/50 transition-colors" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 flex-wrap", children: UNIT_TYPE_LABELS.map((ut) => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setFilterType(ut.key), className: `px-3 py-2 text-sm rounded-lg border transition-colors ${filterType === ut.key
|
|
139
|
+
? 'bg-cyan-700 text-white border-cyan-700'
|
|
140
|
+
: 'bg-transparent border-neutral-700 text-neutral-400 hover:text-neutral-200 hover:border-neutral-500'}`, children: ut.label }, ut.key))) })] }) }), territoriesLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [...Array(6)].map((_, i) => (0, jsx_runtime_1.jsx)(Skeleton, { className: "h-72" }, i)) })) : filteredTerritories.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg hover:border-cyan-400/50 transition-colors", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-12 text-center", children: [(0, jsx_runtime_1.jsx)(IconImage, { className: "w-12 h-12 mx-auto mb-4 text-neutral-600" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400", children: "No territories found" }), searchTerm && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-neutral-500 mt-1", children: "Try adjusting your search or filter criteria" }))] }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: filteredTerritories.map((unit) => ((0, jsx_runtime_1.jsx)(TerritoryCard, { unit: unit, onClick: () => setSelectedId(unit.unit_id) }, unit.unit_id))) }))] }));
|
|
168
141
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,19 +26,27 @@ export type { KPIRadialChartProps } from './components/kpi-radial-chart';
|
|
|
26
26
|
export { MicrocosmDashboardOverview } from './components/dashboard/dashboard-overview';
|
|
27
27
|
export type { MicrocosmDashboardOverviewProps } from './components/dashboard/dashboard-overview';
|
|
28
28
|
export { MicrocosmMarketBar } from './components/dashboard/market-overview-bar';
|
|
29
|
+
export type { MicrocosmMarketBarProps } from './components/dashboard/market-overview-bar';
|
|
29
30
|
export { MicrocosmQuickActions } from './components/dashboard/quick-actions';
|
|
30
31
|
export type { MicrocosmQuickActionsProps } from './components/dashboard/quick-actions';
|
|
31
32
|
export { MicrocosmAssetsSummary } from './components/dashboard/assets-summary';
|
|
32
33
|
export type { MicrocosmAssetsSummaryProps } from './components/dashboard/assets-summary';
|
|
33
34
|
export { MicrocosmPriceChart } from './components/dashboard/price-chart';
|
|
35
|
+
export type { MicrocosmPriceChartProps } from './components/dashboard/price-chart';
|
|
34
36
|
export { MicrocosmMintingStats } from './components/dashboard/minting-stats';
|
|
37
|
+
export type { MicrocosmMintingStatsProps } from './components/dashboard/minting-stats';
|
|
35
38
|
export { MicrocosmMiningWeight } from './components/dashboard/mining-weight';
|
|
39
|
+
export type { MicrocosmMiningWeightProps } from './components/dashboard/mining-weight';
|
|
36
40
|
export { MicrocosmMyMining } from './components/dashboard/my-mining';
|
|
37
41
|
export type { MicrocosmMyMiningProps } from './components/dashboard/my-mining';
|
|
38
42
|
export { MicrocosmEcosystemStats } from './components/dashboard/ecosystem-stats';
|
|
43
|
+
export type { MicrocosmEcosystemStatsProps } from './components/dashboard/ecosystem-stats';
|
|
39
44
|
export { MicrocosmMCCTokenStats } from './components/dashboard/mcc-token-stats';
|
|
45
|
+
export type { MicrocosmMCCTokenStatsProps } from './components/dashboard/mcc-token-stats';
|
|
40
46
|
export { MicrocosmMCDStats } from './components/dashboard/mcd-stats';
|
|
47
|
+
export type { MicrocosmMCDStatsProps } from './components/dashboard/mcd-stats';
|
|
41
48
|
export { MicrocosmLockPeriods } from './components/dashboard/lock-periods';
|
|
49
|
+
export type { MicrocosmLockPeriodsProps } from './components/dashboard/lock-periods';
|
|
42
50
|
export { MicrocosmFragmentPage } from './components/fragment/fragment-page';
|
|
43
51
|
export type { MicrocosmFragmentPageProps } from './components/fragment/fragment-page';
|
|
44
52
|
export { MicrocosmLendingPage } from './components/lending/lending-page';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microcosmmoney/portal-react",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Microcosm Portal UI components for React/Next.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"react": ">=18.0.0",
|
|
16
16
|
"react-dom": ">=18.0.0",
|
|
17
|
-
"recharts": ">=2.0.0"
|
|
17
|
+
"recharts": ">=2.0.0",
|
|
18
|
+
"lucide-react": ">=0.300.0"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@microcosmmoney/auth-core": "file:../auth-core",
|
|
21
|
-
"@microcosmmoney/auth-react": "file:../auth-react"
|
|
22
|
-
"lucide-react": ">=0.300.0"
|
|
22
|
+
"@microcosmmoney/auth-react": "file:../auth-react"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/react": "^18.0.0",
|