@microcosmmoney/portal-react 2.3.4 → 3.0.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/auction/auction-page.js +118 -25
- package/dist/components/dashboard/dashboard-overview.js +1 -1
- package/dist/components/dashboard/market-overview-bar.js +1 -1
- package/dist/components/fragment/fragment-page.js +53 -9
- package/dist/components/lending/lending-page.js +124 -22
- package/dist/components/mcd/mcd-page.js +139 -18
- package/dist/components/mining/mining-page.js +46 -15
- package/dist/components/organization/organization-page.js +90 -22
- package/dist/components/territory/territory-page.js +145 -21
- package/dist/components/voting/voting-page.js +10 -10
- package/dist/components/wallet/wallet-page.js +186 -23
- package/package.json +1 -1
|
@@ -6,19 +6,85 @@ exports.MicrocosmAuctionPage = MicrocosmAuctionPage;
|
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const react_1 = require("react");
|
|
8
8
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
/* ─── Inline SVG Icons (lucide style, 24x24) ─── */
|
|
10
|
+
const IconGavel = ({ className = 'w-4 h-4' }) => ((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 13-7.5 7.5c-.83.83-2.17.83-3 0 0 0 0 0 0 0a2.12 2.12 0 0 1 0-3L11 10" }), (0, jsx_runtime_1.jsx)("path", { d: "m16 16 6-6" }), (0, jsx_runtime_1.jsx)("path", { d: "m8 8 6-6" }), (0, jsx_runtime_1.jsx)("path", { d: "m9 7 8 8" }), (0, jsx_runtime_1.jsx)("path", { d: "m21 11-8-8" })] }));
|
|
11
|
+
const IconFlame = ({ className = 'w-4 h-4' }) => ((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: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z" }) }));
|
|
12
|
+
const IconCrown = ({ className = 'w-4 h-4' }) => ((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: "M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z" }), (0, jsx_runtime_1.jsx)("path", { d: "M5 21h14" })] }));
|
|
13
|
+
const IconTimer = ({ className = 'w-4 h-4' }) => ((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)("line", { x1: "10", x2: "14", y1: "2", y2: "2" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", x2: "12", y1: "14", y2: "10" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "14", r: "8" })] }));
|
|
14
|
+
const IconShield = ({ className = 'w-4 h-4' }) => ((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-.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" }) }));
|
|
15
|
+
const IconClock = ({ className = 'w-4 h-4' }) => ((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)("polyline", { points: "12 6 12 12 16 14" })] }));
|
|
16
|
+
const IconLock = ({ className = 'w-4 h-4' }) => ((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: "11", x: "3", y: "11", rx: "2", ry: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }));
|
|
17
|
+
const IconRefresh = ({ className = 'w-4 h-4' }) => ((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: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }), (0, jsx_runtime_1.jsx)("path", { d: "M21 3v5h-5" }), (0, jsx_runtime_1.jsx)("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 16H3v5" })] }));
|
|
18
|
+
const IconChevronDown = ({ className = 'w-4 h-4' }) => ((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: "m6 9 6 6 6-6" }) }));
|
|
19
|
+
const IconChevronUp = ({ className = 'w-4 h-4' }) => ((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: "m18 15-6-6-6 6" }) }));
|
|
20
|
+
const IconBarChart = ({ className = 'w-4 h-4' }) => ((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: "M3 3v18h18" }), (0, jsx_runtime_1.jsx)("path", { d: "M13 17V9" }), (0, jsx_runtime_1.jsx)("path", { d: "M18 17V5" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 17v-3" })] }));
|
|
21
|
+
const IconAward = ({ className = 'w-4 h-4' }) => ((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: "m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526" }), (0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "8", r: "6" })] }));
|
|
22
|
+
const IconUsers = ({ className = 'w-4 h-4' }) => ((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" })] }));
|
|
23
|
+
const IconZap = ({ className = 'w-4 h-4' }) => ((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: "M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z" }) }));
|
|
24
|
+
const IconArrowUpRight = ({ className = 'w-4 h-4' }) => ((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: "M7 7h10v10" }), (0, jsx_runtime_1.jsx)("path", { d: "M7 17 17 7" })] }));
|
|
25
|
+
const IconBuilding = ({ className = 'w-4 h-4' }) => ((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: "16", height: "20", x: "4", y: "2", rx: "2", ry: "2" }), (0, jsx_runtime_1.jsx)("path", { d: "M9 22v-4h6v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 6h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 6h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 6h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 10h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 14h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 10h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M16 14h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 10h.01" }), (0, jsx_runtime_1.jsx)("path", { d: "M8 14h.01" })] }));
|
|
26
|
+
const IconGrid = ({ className = 'w-4 h-4' }) => ((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" })] }));
|
|
27
|
+
const IconMap = ({ className = 'w-4 h-4' }) => ((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" })] }));
|
|
28
|
+
const IconGlobe = ({ className = 'w-4 h-4' }) => ((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" })] }));
|
|
29
|
+
/* ─── Helpers ─── */
|
|
30
|
+
const UNIT_ICONS = {
|
|
31
|
+
station: (0, jsx_runtime_1.jsx)(IconBuilding, { className: "w-4 h-4" }),
|
|
32
|
+
matrix: (0, jsx_runtime_1.jsx)(IconGrid, { className: "w-4 h-4" }),
|
|
33
|
+
sector: (0, jsx_runtime_1.jsx)(IconMap, { className: "w-4 h-4" }),
|
|
34
|
+
system: (0, jsx_runtime_1.jsx)(IconGlobe, { className: "w-4 h-4" }),
|
|
35
|
+
};
|
|
36
|
+
const UNIT_LABELS = {
|
|
37
|
+
station: 'Station', matrix: 'Matrix', sector: 'Sector', system: 'System',
|
|
38
|
+
};
|
|
39
|
+
const BADGE_VARIANTS = {
|
|
40
|
+
success: 'bg-white/20 text-white border border-white/30',
|
|
41
|
+
warning: 'bg-cyan-400/20 text-cyan-400 border border-cyan-400/30',
|
|
42
|
+
error: 'bg-red-500/20 text-red-500 border border-red-500/30',
|
|
43
|
+
info: 'bg-cyan-400/20 text-cyan-400 border border-cyan-400/30',
|
|
44
|
+
default: 'bg-neutral-500/20 text-neutral-300 border border-neutral-600',
|
|
45
|
+
};
|
|
46
|
+
const BID_STATUS_MAP = {
|
|
47
|
+
active: { label: 'Leading', variant: 'success' },
|
|
48
|
+
outbid: { label: 'Outbid', variant: 'warning' },
|
|
49
|
+
won: { label: 'Won', variant: 'success' },
|
|
50
|
+
lost: { label: 'Lost', variant: 'error' },
|
|
51
|
+
refunded: { label: 'Refunded', variant: 'default' },
|
|
52
|
+
};
|
|
53
|
+
function cn(...classes) {
|
|
54
|
+
return classes.filter(Boolean).join(' ');
|
|
55
|
+
}
|
|
56
|
+
function Badge({ className = '', children }) {
|
|
57
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: cn('inline-flex items-center gap-0.5 text-[10px] font-medium px-2 py-0.5 rounded-full whitespace-nowrap', className), children: children }));
|
|
58
|
+
}
|
|
59
|
+
function TimeRemaining({ endTime, className }) {
|
|
60
|
+
const diff = new Date(endTime).getTime() - Date.now();
|
|
61
|
+
if (diff <= 0)
|
|
62
|
+
return (0, jsx_runtime_1.jsx)("span", { className: className, children: "Ended" });
|
|
63
|
+
const d = Math.floor(diff / 86400000);
|
|
64
|
+
const h = Math.floor((diff % 86400000) / 3600000);
|
|
65
|
+
const m = Math.floor((diff % 3600000) / 60000);
|
|
66
|
+
const parts = [];
|
|
67
|
+
if (d > 0)
|
|
68
|
+
parts.push(`${d}d`);
|
|
69
|
+
parts.push(`${h}h`);
|
|
70
|
+
parts.push(`${m}m`);
|
|
71
|
+
return (0, jsx_runtime_1.jsx)("span", { className: className, children: parts.join(' ') });
|
|
72
|
+
}
|
|
73
|
+
function FormattedDateTime({ dateTime, className }) {
|
|
74
|
+
if (!dateTime)
|
|
75
|
+
return (0, jsx_runtime_1.jsx)("span", { className: className, children: "-" });
|
|
76
|
+
const d = new Date(dateTime);
|
|
77
|
+
return (0, jsx_runtime_1.jsxs)("span", { className: className, children: [d.toLocaleDateString(), " ", d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })] });
|
|
12
78
|
}
|
|
13
79
|
function Modal({ open, onClose, children }) {
|
|
14
80
|
if (!open)
|
|
15
81
|
return null;
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", onClick: onClose, children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 bg-black/60" }), (0, jsx_runtime_1.jsx)("div", { className: "relative bg-neutral-900 border border-neutral-700 rounded-lg
|
|
82
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", onClick: onClose, children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 bg-black/60" }), (0, jsx_runtime_1.jsx)("div", { className: "relative bg-neutral-900 border border-neutral-700 rounded-lg max-w-md w-full mx-4 font-mono max-h-[90vh] overflow-y-auto", onClick: e => e.stopPropagation(), children: children })] }));
|
|
17
83
|
}
|
|
18
84
|
function MicrocosmAuctionPage({ basePath = '', onNavigate }) {
|
|
19
|
-
const { data: auctions, loading, refresh: refreshAuctions } = (0, auth_react_1.useAuctions)();
|
|
20
|
-
const { data: myBids, refresh: refreshBids } = (0, auth_react_1.useMyBids)();
|
|
21
|
-
const { data: history } = (0, auth_react_1.useAuctionHistory)();
|
|
85
|
+
const { data: auctions, loading, refresh: refreshAuctions } = (0, auth_react_1.useAuctions)({ refetchInterval: 30000 });
|
|
86
|
+
const { data: myBids, refresh: refreshBids } = (0, auth_react_1.useMyBids)({ refetchInterval: 30000 });
|
|
87
|
+
const { data: history, refresh: refreshHistory } = (0, auth_react_1.useAuctionHistory)();
|
|
22
88
|
const { placeBid, loading: bidLoading } = (0, auth_react_1.useAuctionBid)();
|
|
23
89
|
const [bidDialogOpen, setBidDialogOpen] = (0, react_1.useState)(false);
|
|
24
90
|
const [selectedAuction, setSelectedAuction] = (0, react_1.useState)(null);
|
|
@@ -30,41 +96,68 @@ function MicrocosmAuctionPage({ basePath = '', onNavigate }) {
|
|
|
30
96
|
const auctionList = Array.isArray(auctions) ? auctions : [];
|
|
31
97
|
const bidsList = Array.isArray(myBids) ? myBids : [];
|
|
32
98
|
const historyList = Array.isArray(history) ? history : [];
|
|
33
|
-
const
|
|
34
|
-
|
|
99
|
+
const stats = (0, react_1.useMemo)(() => {
|
|
100
|
+
const totalBids = auctionList.reduce((s, a) => s + (a.bid_count || 0), 0);
|
|
101
|
+
const highestBid = auctionList.length > 0 ? Math.max(...auctionList.map((a) => a.current_price ?? 0)) : 0;
|
|
102
|
+
const totalVolume = auctionList.reduce((s, a) => s + (a.current_price ?? 0), 0);
|
|
103
|
+
const myLeading = bidsList.filter((b) => b.status === 'active').length;
|
|
104
|
+
return { totalBids, highestBid, totalVolume, myLeading };
|
|
105
|
+
}, [auctionList, bidsList]);
|
|
35
106
|
const handleRefresh = (0, react_1.useCallback)(async () => {
|
|
36
107
|
setRefreshing(true);
|
|
37
|
-
await Promise.all([refreshAuctions(), refreshBids()]);
|
|
108
|
+
await Promise.all([refreshAuctions(), refreshBids(), refreshHistory()]);
|
|
38
109
|
setRefreshing(false);
|
|
39
|
-
}, [refreshAuctions, refreshBids]);
|
|
40
|
-
const
|
|
110
|
+
}, [refreshAuctions, refreshBids, refreshHistory]);
|
|
111
|
+
const openBidDialog = (auction) => {
|
|
112
|
+
setSelectedAuction(auction);
|
|
113
|
+
setBidAmount(((auction.current_price ?? 0) + (auction.bid_increment ?? 0)).toString());
|
|
114
|
+
setBidDialogOpen(true);
|
|
115
|
+
setActionError(null);
|
|
116
|
+
};
|
|
117
|
+
const handlePlaceBid = async () => {
|
|
41
118
|
if (!selectedAuction)
|
|
42
119
|
return;
|
|
43
120
|
const amount = parseFloat(bidAmount);
|
|
44
121
|
if (isNaN(amount) || amount <= 0) {
|
|
45
|
-
setActionError('Enter a valid amount');
|
|
122
|
+
setActionError('Enter a valid bid amount');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const minBid = (selectedAuction.current_price ?? 0) + (selectedAuction.bid_increment ?? 0);
|
|
126
|
+
if (amount < minBid) {
|
|
127
|
+
setActionError(`Minimum bid is ${minBid.toLocaleString()} MCC`);
|
|
46
128
|
return;
|
|
47
129
|
}
|
|
48
130
|
try {
|
|
49
131
|
setActionError(null);
|
|
50
|
-
await placeBid(selectedAuction.id, amount);
|
|
132
|
+
await placeBid(selectedAuction.auction_id ?? selectedAuction.id, amount);
|
|
51
133
|
setBidDialogOpen(false);
|
|
52
134
|
setBidAmount('');
|
|
135
|
+
setSelectedAuction(null);
|
|
53
136
|
handleRefresh();
|
|
54
137
|
}
|
|
55
138
|
catch (err) {
|
|
56
139
|
setActionError(err instanceof Error ? err.message : 'Bid failed');
|
|
57
140
|
}
|
|
58
141
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-2xl font-bold text-white", children: "Auctions" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-1", children: "Territory magistrate auctions" })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: handleRefresh, disabled: refreshing, className: "flex items-center gap-2 px-3 py-1.5 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 disabled:opacity-50 bg-transparent", children: [(0, jsx_runtime_1.jsx)("svg", { className: `w-4 h-4 ${refreshing ? 'animate-spin' : ''}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }), "Refresh"] })] }), actionError && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-500/10 border border-red-500/30 rounded text-red-400 text-sm", children: actionError })), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "ongoing" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold text-cyan-400", children: auctionList.length })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "total_bids" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold text-white", children: totalBids })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "highest_bid" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xl font-bold text-cyan-400", children: [fmt(highestBid), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "my_bids" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold text-white", children: bidsList.length })] })] }), (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-6", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400 text-xs font-mono tracking-wider mb-4 block", children: "ACTIVE_AUCTIONS" }), loading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)(Spinner, {}) })) : auctionList.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: auctionList.map((a) => ((0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700 hover:border-cyan-400/50 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-start mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold", children: a.unit_name || a.territory_id || `Auction #${a.id}` }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400 mt-0.5", children: [a.unit_type || 'Station', " \u2022 ", a.bid_count ?? 0, " bids", (a.bid_count ?? 0) >= 5 && (0, jsx_runtime_1.jsx)("span", { className: "text-cyan-400 ml-1", children: "\uD83D\uDD25 Hot" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400", children: "Time Left" }), (0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold", children: formatTimeLeft(a.end_time) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-3 gap-3 mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-400", children: "starting_price" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm font-bold text-white", children: [fmt(a.starting_price ?? 0), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-400", children: "current_highest" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm font-bold text-cyan-400", children: [fmt(a.current_price ?? a.starting_price ?? 0), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-[10px] text-neutral-400", children: "bid_increment" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm font-bold text-white", children: [fmt(a.bid_increment ?? 0), " MCC"] })] })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => { setSelectedAuction(a); setBidDialogOpen(true); setActionError(null); }, className: "w-full py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm font-mono", children: "Place Bid" })] }, a.id))) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500 font-mono text-sm", children: "no active auctions" }))] }) }), (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-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_BIDS" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowMyBids(!showMyBids), className: "text-xs text-neutral-500 hover:text-cyan-400 font-mono", children: showMyBids ? 'Collapse' : 'Expand' })] }), showMyBids && (bidsList.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-2", children: bidsList.map((b, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between p-3 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white text-sm", children: b.unit_name || `Auction #${b.auction_id}` }), (0, jsx_runtime_1.jsx)("span", { className: `ml-2 text-[10px] px-1.5 py-0.5 rounded ${b.status === 'active' || b.status === 'leading' ? 'bg-cyan-400/20 text-cyan-400' : b.status === 'won' ? 'bg-white/20 text-white' : 'bg-neutral-700 text-neutral-400'}`, children: b.status || 'active' })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-bold font-mono", children: [fmt(b.amount ?? 0), " MCC"] })] }, i))) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500 font-mono text-sm", children: "no bids placed" })))] }) }), (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-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: "AUCTION_HISTORY" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setShowHistory(!showHistory), className: "text-xs text-neutral-500 hover:text-cyan-400 font-mono", children: showHistory ? 'Collapse' : 'Expand' })] }), showHistory && (historyList.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { className: "text-neutral-400 text-xs border-b border-neutral-700", children: [(0, jsx_runtime_1.jsx)("th", { className: "text-left py-2 font-normal", children: "Territory" }), (0, jsx_runtime_1.jsx)("th", { className: "text-right py-2 font-normal", children: "Final Price" }), (0, jsx_runtime_1.jsx)("th", { className: "text-right py-2 font-normal", children: "Bids" }), (0, jsx_runtime_1.jsx)("th", { className: "text-right py-2 font-normal", children: "Status" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: historyList.map((h, i) => ((0, jsx_runtime_1.jsxs)("tr", { className: "border-b border-neutral-800", children: [(0, jsx_runtime_1.jsx)("td", { className: "py-3 text-white", children: h.unit_name || h.territory_id || '-' }), (0, jsx_runtime_1.jsxs)("td", { className: "py-3 text-right text-cyan-400 font-bold", children: [fmt(h.final_price ?? 0), " MCC"] }), (0, jsx_runtime_1.jsx)("td", { className: "py-3 text-right text-neutral-400", children: h.bid_count ?? 0 }), (0, jsx_runtime_1.jsx)("td", { className: "py-3 text-right", children: (0, jsx_runtime_1.jsx)("span", { className: "text-xs bg-neutral-700 text-neutral-300 px-1.5 py-0.5 rounded", children: h.status || 'ended' }) })] }, i))) })] }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-4 text-neutral-500 font-mono text-sm", children: "no auction history" })))] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg p-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-400 text-xs font-mono tracking-wider mb-4", children: "AUCTION_RULES" }), (0, jsx_runtime_1.jsxs)("div", { className: "grid md:grid-cols-3 gap-4 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-3 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold mb-2", children: "Target" }), (0, jsx_runtime_1.jsxs)("ul", { className: "list-disc list-inside text-neutral-400 space-y-1", children: [(0, jsx_runtime_1.jsx)("li", { children: "Territory magistrate position" }), (0, jsx_runtime_1.jsx)("li", { children: "Station / Matrix / Sector / System" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold mb-2", children: "Bidding Rules" }), (0, jsx_runtime_1.jsxs)("ul", { className: "list-disc list-inside text-neutral-400 space-y-1", children: [(0, jsx_runtime_1.jsx)("li", { children: "50% deposit required" }), (0, jsx_runtime_1.jsx)("li", { children: "24h no-bid rule ends auction" }), (0, jsx_runtime_1.jsx)("li", { children: "Winner becomes magistrate" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold mb-2", children: "Requirements" }), (0, jsx_runtime_1.jsxs)("ul", { className: "list-disc list-inside text-neutral-400 space-y-1", children: [(0, jsx_runtime_1.jsx)("li", { children: "Sufficient MCC balance" }), (0, jsx_runtime_1.jsx)("li", { children: "Miner level or above" })] })] })] })] }), (0, jsx_runtime_1.jsx)(Modal, { open: bidDialogOpen, onClose: () => setBidDialogOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-bold text-white", children: "Place Bid" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400 mt-1", children: selectedAuction?.unit_name || `Auction #${selectedAuction?.id}` })] }), selectedAuction && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Current Highest" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-cyan-400 font-bold", children: [fmt(selectedAuction.current_price ?? selectedAuction.starting_price ?? 0), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Min Next Bid" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-bold", children: [fmt((selectedAuction.current_price ?? selectedAuction.starting_price ?? 0) + (selectedAuction.bid_increment ?? 0)), " MCC"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-neutral-400 tracking-wider", children: "bid_amount (MCC)" }), (0, jsx_runtime_1.jsx)("input", { type: "number", step: "0.01", value: bidAmount, onChange: e => setBidAmount(e.target.value), placeholder: "Enter bid amount", className: "w-full px-3 py-2 bg-neutral-800 border border-neutral-600 rounded text-white placeholder-neutral-400 outline-none focus:border-cyan-400" })] }), bidAmount && parseFloat(bidAmount) > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "p-3 bg-neutral-800 rounded border border-neutral-700 text-xs text-neutral-400", children: ["Deposit required: ", (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-bold", children: [fmt(parseFloat(bidAmount) * 0.5), " MCC"] }), " (50%)"] }))] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setBidDialogOpen(false), className: "px-4 py-2 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 bg-transparent", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBid, disabled: bidLoading || !bidAmount, className: "px-4 py-2 text-sm bg-cyan-700 hover:bg-cyan-600 text-white rounded disabled:opacity-50", children: bidLoading ? 'Processing...' : 'Confirm Bid' })] })] }) })] }));
|
|
142
|
+
if (loading)
|
|
143
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center h-[60vh]", children: (0, jsx_runtime_1.jsx)("span", { className: "inline-block w-8 h-8 border-2 border-neutral-400 border-t-transparent rounded-full animate-spin" }) }));
|
|
144
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto p-6 space-y-6 font-mono", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-2xl font-bold text-white tracking-wider", children: "Territory Auctions" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400", children: "Bid for magistrate positions across the Microcosm" })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: handleRefresh, disabled: refreshing, className: "flex items-center gap-2 px-3 py-1.5 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 hover:text-neutral-300 disabled:opacity-50 bg-transparent", children: [(0, jsx_runtime_1.jsx)(IconRefresh, { className: cn('w-4 h-4', refreshing && 'animate-spin') }), "Refresh"] })] }), actionError && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-red-500/10 border border-red-500/30 rounded text-red-400 text-sm", children: actionError })), (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg", children: (0, jsx_runtime_1.jsx)("div", { className: "p-6", children: (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Ongoing" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400 font-mono", children: auctionList.length }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "auctions" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Total Bids" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-white font-mono", children: stats.totalBids }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "bids" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Highest Bid" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400 font-mono", children: stats.highestBid > 0 ? stats.highestBid.toLocaleString() : '--' }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "MCC" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 rounded p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Total Locked" }), (0, jsx_runtime_1.jsx)("div", { className: "text-2xl font-bold text-cyan-400 font-mono", children: stats.totalVolume > 0 ? stats.totalVolume.toLocaleString() : '--' }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "MCC" })] })] }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg", 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.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconFlame, { className: "w-4 h-4 text-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-neutral-300 tracking-wider", children: "Active Auctions" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-neutral-500", children: ["(", auctionList.length, ")"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-xs text-neutral-500", children: [(0, jsx_runtime_1.jsx)(IconClock, { className: "w-3 h-3" }), (0, jsx_runtime_1.jsx)("span", { children: "Auto-refresh 30s" })] })] }), auctionList.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-16", children: [(0, jsx_runtime_1.jsx)(IconGavel, { className: "w-10 h-10 text-neutral-700 mx-auto mb-3" }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-sm mb-2", children: "No active auctions" }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-xs max-w-md mx-auto", children: "Auctions are held for magistrate positions. When a territory opens for bidding, it will appear here." })] })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: auctionList.map((auction) => {
|
|
145
|
+
const unitType = auction.unit_type || 'station';
|
|
146
|
+
const currentPrice = auction.current_price ?? auction.starting_price ?? 0;
|
|
147
|
+
const startingPrice = auction.starting_price ?? 0;
|
|
148
|
+
const bidIncrement = auction.bid_increment ?? 0;
|
|
149
|
+
const minNextBid = currentPrice + bidIncrement;
|
|
150
|
+
const priceUp = startingPrice > 0
|
|
151
|
+
? ((currentPrice - startingPrice) / startingPrice * 100).toFixed(1)
|
|
152
|
+
: '0';
|
|
153
|
+
const isHot = (auction.bid_count || 0) >= 5;
|
|
154
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: cn('bg-neutral-800 border rounded p-5 hover:border-cyan-400/50 transition-colors', isHot ? 'border-cyan-400/30' : 'border-neutral-700'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-cyan-400", children: UNIT_ICONS[unitType] || UNIT_ICONS.station }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-white font-bold", children: auction.unit_name || `Territory #${auction.unit_id || auction.auction_id || auction.id}` }), isHot && ((0, jsx_runtime_1.jsxs)(Badge, { className: BADGE_VARIANTS.warning, children: [(0, jsx_runtime_1.jsx)(IconFlame, { className: "w-3 h-3" }), "Hot"] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [(0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS.info, children: UNIT_LABELS[unitType] || 'Station' }), (0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS.default, children: auction.auction_type === 'first' ? 'First Auction' : auction.auction_type === 'second' ? 'Second Auction' : 'Auction' }), (0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS.success, children: "Active" })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 bg-neutral-800 border border-neutral-700 rounded px-3 py-1.5 text-sm", children: [(0, jsx_runtime_1.jsx)(IconClock, { className: "w-3.5 h-3.5 text-cyan-400" }), (0, jsx_runtime_1.jsx)(TimeRemaining, { endTime: auction.end_time, className: "text-cyan-400 font-bold font-mono" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-3 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 border border-neutral-700 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Starting Price" }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-300 font-mono", children: startingPrice.toLocaleString() }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "MCC" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-900 border border-neutral-700 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Current Highest" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xl font-bold text-cyan-400 font-mono", children: currentPrice.toLocaleString() }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 text-xs", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-500", children: "MCC" }), Number(priceUp) > 0 && ((0, jsx_runtime_1.jsxs)("span", { className: "text-white flex items-center", children: [(0, jsx_runtime_1.jsx)(IconArrowUpRight, { className: "w-3 h-3" }), "+", priceUp, "%"] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 border border-neutral-700 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Bid Count" }), (0, jsx_runtime_1.jsx)("div", { className: "text-white font-bold font-mono", children: auction.bid_count || 0 }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "bids" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 border border-neutral-700 rounded p-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Min Increment" }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-300 font-mono", children: bidIncrement.toLocaleString() }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500", children: ["MCC (", '\u2265', "5%)"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4 text-xs text-neutral-500", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconLock, { className: "w-3 h-3" }), "50% deposit"] }), (0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconCrown, { className: "w-3 h-3" }), "Winner = Magistrate"] }), (0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconTimer, { className: "w-3 h-3" }), "24h no-bid ends"] })] }), (auction.status === 'active' || !auction.status) && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => openBidDialog(auction), className: "flex items-center gap-2 px-4 py-2 bg-cyan-700 hover:bg-cyan-600 text-white rounded text-sm font-mono", children: [(0, jsx_runtime_1.jsx)(IconGavel, { className: "w-4 h-4" }), "Place Bid"] }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => openBidDialog(auction), className: "flex items-center gap-1.5 px-3 py-1.5 text-xs border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 hover:text-neutral-300 bg-transparent", children: [(0, jsx_runtime_1.jsx)(IconZap, { className: "w-3 h-3" }), minNextBid.toLocaleString(), " MCC"] })] }))] })] }, auction.auction_id ?? auction.id));
|
|
155
|
+
}) }))] }) }), (0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg", children: (0, jsx_runtime_1.jsx)("div", { className: "p-6", children: (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-1 md: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-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconAward, { className: "w-3.5 h-3.5 text-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: "Auction Target" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-neutral-300 mb-1", children: "Territory magistrate positions" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Station / Matrix / Sector / System levels" })] }), (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-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconTimer, { className: "w-3.5 h-3.5 text-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: "Bidding Rules" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-neutral-300 mb-1", children: ["50% deposit, ", '\u2265', "5% increment"] }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "24h with no new bids ends the auction" })] }), (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-2 mb-2", children: [(0, jsx_runtime_1.jsx)(IconUsers, { className: "w-3.5 h-3.5 text-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: "Participation" })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-sm text-neutral-300 mb-1", children: "Sufficient MCC balance required" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-500", children: "Miner level or above to participate" })] })] }) }) }), bidsList.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { onClick: () => setShowMyBids(!showMyBids), className: "flex items-center justify-between cursor-pointer", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconShield, { className: "w-4 h-4 text-cyan-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-300 tracking-wider", children: "My Bids" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-neutral-500", children: [bidsList.length, " bids"] }), stats.myLeading > 0 && (0, jsx_runtime_1.jsxs)(Badge, { className: BADGE_VARIANTS.success, children: [stats.myLeading, " leading"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-4", children: showMyBids
|
|
156
|
+
? (0, jsx_runtime_1.jsx)(IconChevronUp, { className: "w-4 h-4 text-neutral-500" })
|
|
157
|
+
: (0, jsx_runtime_1.jsx)(IconChevronDown, { className: "w-4 h-4 text-neutral-500" }) })] }), showMyBids && ((0, jsx_runtime_1.jsx)("div", { className: "mt-4 space-y-2", children: bidsList.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "text-center py-8 text-neutral-500 text-sm", children: "No bid records" })) : bidsList.map((bid, idx) => {
|
|
158
|
+
const si = BID_STATUS_MAP[bid.status] || { label: bid.status || 'active', variant: 'default' };
|
|
159
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between bg-neutral-800 border border-neutral-700 rounded p-3 hover:bg-neutral-700 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS[si.variant] || BADGE_VARIANTS.default, children: si.label }), (0, jsx_runtime_1.jsx)("span", { className: "text-neutral-300 text-sm", children: bid.unit_name || `#${bid.auction_id}` }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white text-sm font-bold font-mono", children: [(bid.bid_amount ?? bid.amount ?? 0).toLocaleString(), " MCC"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-3", children: bid.created_at && (0, jsx_runtime_1.jsx)(FormattedDateTime, { dateTime: bid.created_at, className: "text-neutral-500 text-xs font-mono" }) })] }, bid.bid_id ?? idx));
|
|
160
|
+
}) }))] }) })), historyList.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "bg-neutral-900 border border-neutral-700 rounded-lg", children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6", children: [(0, jsx_runtime_1.jsxs)("div", { onClick: () => setShowHistory(!showHistory), className: "flex items-center justify-between cursor-pointer", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconBarChart, { className: "w-4 h-4 text-neutral-400" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-neutral-300 tracking-wider", children: "Auction History" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-neutral-500", children: [historyList.length, " auctions"] })] }), showHistory
|
|
161
|
+
? (0, jsx_runtime_1.jsx)(IconChevronUp, { className: "w-4 h-4 text-neutral-500" })
|
|
162
|
+
: (0, jsx_runtime_1.jsx)(IconChevronDown, { className: "w-4 h-4 text-neutral-500" })] }), showHistory && ((0, jsx_runtime_1.jsx)("div", { className: "mt-4 space-y-2", children: historyList.map((a, idx) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between bg-neutral-800 border border-neutral-700 rounded p-3 hover:bg-neutral-700 transition-colors", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-cyan-400", children: UNIT_ICONS[a.unit_type || 'station'] || UNIT_ICONS.station }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-neutral-300 text-sm", children: a.unit_name || `Territory #${a.unit_id || a.auction_id}` }), (0, jsx_runtime_1.jsx)("div", { className: "text-neutral-500 text-xs", children: UNIT_LABELS[a.unit_type || 'station'] || 'Station' })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-white text-sm font-bold font-mono", children: [(a.current_price ?? a.final_price ?? 0).toLocaleString(), " MCC"] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-neutral-500 text-xs", children: [a.bid_count || 0, " bids"] })] }), (0, jsx_runtime_1.jsx)(Badge, { className: a.status === 'cancelled' ? BADGE_VARIANTS.error : BADGE_VARIANTS.default, children: a.status === 'ended' ? 'Ended' : a.status === 'cancelled' ? 'Cancelled' : 'Sold' })] })] }, a.auction_id ?? idx))) }))] }) })), (0, jsx_runtime_1.jsx)(Modal, { open: bidDialogOpen, onClose: () => setBidDialogOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "p-6 space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-white font-mono font-bold flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(IconGavel, { className: "w-5 h-5 text-cyan-400" }), "Place Bid"] }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 font-mono text-sm mt-1", children: selectedAuction?.unit_name || `Territory #${selectedAuction?.unit_id || selectedAuction?.auction_id || selectedAuction?.id}` })] }), selectedAuction && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2 flex-wrap", children: [(0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS.info, children: UNIT_LABELS[selectedAuction.unit_type || 'station'] || 'Station' }), (0, jsx_runtime_1.jsx)(Badge, { className: BADGE_VARIANTS.default, children: selectedAuction.auction_type === 'first' ? 'First Auction' : selectedAuction.auction_type === 'second' ? 'Second Auction' : 'Auction' }), (0, jsx_runtime_1.jsxs)(Badge, { className: BADGE_VARIANTS.warning, children: [(0, jsx_runtime_1.jsx)(IconCrown, { className: "w-3 h-3" }), "Winner = Magistrate"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bg-neutral-800 border border-neutral-700 rounded p-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: "Current Highest" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-3xl font-bold text-cyan-400 font-mono", children: [(selectedAuction.current_price ?? selectedAuction.starting_price ?? 0).toLocaleString(), ' ', (0, jsx_runtime_1.jsx)("span", { className: "text-base text-neutral-500", children: "MCC" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-500 mt-1", children: [selectedAuction.bid_count || 0, " bids \u00B7 Starting price ", (selectedAuction.starting_price ?? 0).toLocaleString(), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center p-3 bg-neutral-800 rounded border border-neutral-700 text-sm", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Min Next Bid" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-bold font-mono", children: [((selectedAuction.current_price ?? selectedAuction.starting_price ?? 0) + (selectedAuction.bid_increment ?? 0)).toLocaleString(), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400 tracking-wider mb-1", children: ["Bid Amount (min ", ((selectedAuction.current_price ?? 0) + (selectedAuction.bid_increment ?? 0)).toLocaleString(), " MCC)"] }), (0, jsx_runtime_1.jsx)("input", { type: "number", step: selectedAuction.bid_increment ?? 1, value: bidAmount, onChange: (e) => setBidAmount(e.target.value), placeholder: "Enter bid amount", className: "w-full bg-neutral-800 border border-neutral-600 text-white placeholder-neutral-400 px-3 py-2.5 rounded text-sm font-mono focus:border-cyan-400 focus:outline-none" })] }), bidAmount && !isNaN(parseFloat(bidAmount)) && parseFloat(bidAmount) > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2 p-3 bg-neutral-800 rounded border border-neutral-700 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Bid Amount:" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-neutral-300 font-mono", children: [parseFloat(bidAmount).toLocaleString(), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Deposit (50%):" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-cyan-400 font-mono", children: [(parseFloat(bidAmount) * 0.5).toLocaleString(), " MCC"] })] })] })), actionError && ((0, jsx_runtime_1.jsxs)("div", { className: "text-red-500 text-xs flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(IconLock, { className: "w-3 h-3" }), actionError] }))] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setBidDialogOpen(false), className: "px-4 py-2 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 hover:text-neutral-300 bg-transparent", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handlePlaceBid, disabled: bidLoading || !bidAmount, className: "px-4 py-2 text-sm bg-cyan-700 hover:bg-cyan-600 text-white rounded disabled:opacity-50 font-mono", children: bidLoading ? 'Processing...' : 'Confirm Bid' })] })] }) })] }));
|
|
70
163
|
}
|
|
@@ -50,5 +50,5 @@ function LazySection({ children, fallback }) {
|
|
|
50
50
|
return (0, jsx_runtime_1.jsx)("div", { ref: ref, children: visible ? children : fallback });
|
|
51
51
|
}
|
|
52
52
|
function MicrocosmDashboardOverview({ basePath = '', onNavigate, showHeader = true, headerText = 'SHARED NETWORK · SHARED FUTURE', }) {
|
|
53
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono p-6 space-y-6", children: [showHeader && ((0, jsx_runtime_1.jsx)("div", { className: "text-center", children: (0, jsx_runtime_1.jsx)("h1", { className: "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", children: headerText }) })), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(market_overview_bar_1.MicrocosmMarketBar, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(quick_actions_1.MicrocosmQuickActions, { basePath: basePath, onNavigate: onNavigate }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(assets_summary_1.MicrocosmAssetsSummary, { basePath: basePath, onNavigate: onNavigate }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(price_chart_1.MicrocosmPriceChart, {}) }), (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 }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mining_weight_1.MicrocosmMiningWeight, {}) })] }) }), (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, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(ecosystem_stats_1.MicrocosmEcosystemStats, {}) })] }) }), (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, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mcd_stats_1.MicrocosmMCDStats, {}) })] }) }), (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, {}) }) })] }));
|
|
53
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono p-6 space-y-6", children: [showHeader && ((0, jsx_runtime_1.jsx)("div", { className: "text-center", children: (0, jsx_runtime_1.jsx)("h1", { className: "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", children: headerText }) })), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(market_overview_bar_1.MicrocosmMarketBar, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(quick_actions_1.MicrocosmQuickActions, { basePath: basePath, onNavigate: onNavigate }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(assets_summary_1.MicrocosmAssetsSummary, { basePath: basePath, onNavigate: onNavigate }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(price_chart_1.MicrocosmPriceChart, {}) }), (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 }) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mining_weight_1.MicrocosmMiningWeight, {}) })] }) }), (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, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(ecosystem_stats_1.MicrocosmEcosystemStats, {}) })] }) }), (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, {}) }), (0, jsx_runtime_1.jsx)(SafeRender, { children: (0, jsx_runtime_1.jsx)(mcd_stats_1.MicrocosmMCDStats, {}) })] }) }), (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, {}) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-center py-4 space-y-1", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400/60 font-mono", children: "Data refreshes every 4 hours \u00B7 For real-time data, please check on-chain directly" }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-cyan-400/60 font-mono", 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: "text-xs text-cyan-400/60 font-mono", 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: "text-xs text-cyan-400/60 font-mono", 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
54
|
}
|
|
@@ -36,5 +36,5 @@ function MicrocosmMarketBar() {
|
|
|
36
36
|
{ label: '24H_TRADES', value: `${trades}`, color: 'text-cyan-400' },
|
|
37
37
|
{ label: 'BUY/SELL', value: `${buys}/${sells}`, color: 'text-white' },
|
|
38
38
|
];
|
|
39
|
-
return ((0, jsx_runtime_1.
|
|
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))) }));
|
|
40
40
|
}
|
|
@@ -6,16 +6,40 @@ exports.MicrocosmFragmentPage = MicrocosmFragmentPage;
|
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const react_1 = require("react");
|
|
8
8
|
const auth_react_1 = require("@microcosmmoney/auth-react");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const formatNumber = (num, decimals = 2) => num.toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
|
|
10
|
+
const formatMCC = (lamports) => formatNumber(lamports / 1000000000, 2);
|
|
11
|
+
/* ── Inline SVG Icons (lucide style) ── */
|
|
12
|
+
function IconRefreshCw({ className }) {
|
|
13
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { d: "M21 2v6h-6" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 12a9 9 0 0115.15-6.64L21 8" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 22v-6h6" }), (0, jsx_runtime_1.jsx)("path", { d: "M21 12a9 9 0 01-15.15 6.64L3 16" })] }));
|
|
13
14
|
}
|
|
15
|
+
function IconWallet({ className }) {
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { d: "M19 7V4a1 1 0 00-1-1H5a2 2 0 000 4h15a1 1 0 011 1v4h-3a2 2 0 000 4h3a1 1 0 001-1v-2a1 1 0 00-1-1" }), (0, jsx_runtime_1.jsx)("path", { d: "M3 5v14a2 2 0 002 2h15a1 1 0 001-1v-4" })] }));
|
|
17
|
+
}
|
|
18
|
+
function IconPuzzle({ className }) {
|
|
19
|
+
return ((0, jsx_runtime_1.jsx)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { d: "M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z" }) }));
|
|
20
|
+
}
|
|
21
|
+
function IconImage({ className }) {
|
|
22
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }), (0, jsx_runtime_1.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5" }), (0, jsx_runtime_1.jsx)("path", { d: "M21 15l-5-5L5 21" })] }));
|
|
23
|
+
}
|
|
24
|
+
function IconShoppingCart({ className }) {
|
|
25
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "9", cy: "21", r: "1" }), (0, jsx_runtime_1.jsx)("circle", { cx: "20", cy: "21", r: "1" }), (0, jsx_runtime_1.jsx)("path", { d: "M1 1h4l2.68 13.39a2 2 0 002 1.61h9.72a2 2 0 002-1.61L23 6H6" })] }));
|
|
26
|
+
}
|
|
27
|
+
function IconInfo({ className }) {
|
|
28
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 16v-4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 8h.01" })] }));
|
|
29
|
+
}
|
|
30
|
+
function IconAlertTriangle({ className }) {
|
|
31
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { d: "M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 9v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 17h.01" })] }));
|
|
32
|
+
}
|
|
33
|
+
function IconLoader({ className }) {
|
|
34
|
+
return ((0, jsx_runtime_1.jsxs)("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", viewBox: "0 0 24 24", children: [(0, jsx_runtime_1.jsx)("path", { d: "M12 2v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M12 18v4" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.93 4.93l2.83 2.83" }), (0, jsx_runtime_1.jsx)("path", { d: "M16.24 16.24l2.83 2.83" }), (0, jsx_runtime_1.jsx)("path", { d: "M2 12h4" }), (0, jsx_runtime_1.jsx)("path", { d: "M18 12h4" }), (0, jsx_runtime_1.jsx)("path", { d: "M4.93 19.07l2.83-2.83" }), (0, jsx_runtime_1.jsx)("path", { d: "M16.24 7.76l2.83-2.83" })] }));
|
|
35
|
+
}
|
|
36
|
+
/* ── Modal ── */
|
|
14
37
|
function Modal({ open, onClose, children }) {
|
|
15
38
|
if (!open)
|
|
16
39
|
return null;
|
|
17
40
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center", onClick: onClose, children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 bg-black/60" }), (0, jsx_runtime_1.jsx)("div", { className: "relative bg-neutral-900 border border-neutral-700 rounded-lg p-6 max-w-md w-full mx-4 font-mono", onClick: e => e.stopPropagation(), children: children })] }));
|
|
18
41
|
}
|
|
42
|
+
/* ── Main Component ── */
|
|
19
43
|
function MicrocosmFragmentPage({ onNavigate }) {
|
|
20
44
|
const { data: wallets } = (0, auth_react_1.useWallets)();
|
|
21
45
|
const primaryWallet = wallets?.[0]?.wallet_address;
|
|
@@ -28,15 +52,23 @@ function MicrocosmFragmentPage({ onNavigate }) {
|
|
|
28
52
|
const [refreshing, setRefreshing] = (0, react_1.useState)(false);
|
|
29
53
|
const [actionError, setActionError] = (0, react_1.useState)(null);
|
|
30
54
|
const [actionSuccess, setActionSuccess] = (0, react_1.useState)(null);
|
|
55
|
+
const [initialLoaded, setInitialLoaded] = (0, react_1.useState)(false);
|
|
31
56
|
const loading = vLoading || hLoading;
|
|
57
|
+
(0, react_1.useEffect)(() => {
|
|
58
|
+
if (!loading && !initialLoaded) {
|
|
59
|
+
setInitialLoaded(true);
|
|
60
|
+
}
|
|
61
|
+
}, [loading, initialLoaded]);
|
|
32
62
|
const handleRefresh = (0, react_1.useCallback)(async () => {
|
|
33
63
|
setRefreshing(true);
|
|
34
64
|
await Promise.all([refreshVaults(), refreshHoldings()]);
|
|
35
65
|
setRefreshing(false);
|
|
36
66
|
}, [refreshVaults, refreshHoldings]);
|
|
37
67
|
const handleBuy = async () => {
|
|
38
|
-
if (!selectedVault)
|
|
68
|
+
if (!selectedVault) {
|
|
69
|
+
setActionError('Please select a vault');
|
|
39
70
|
return;
|
|
71
|
+
}
|
|
40
72
|
const amount = parseInt(buyAmount);
|
|
41
73
|
if (isNaN(amount) || amount <= 0) {
|
|
42
74
|
setActionError('Please enter a valid amount');
|
|
@@ -55,8 +87,20 @@ function MicrocosmFragmentPage({ onNavigate }) {
|
|
|
55
87
|
setActionError(err instanceof Error ? err.message : 'Purchase failed');
|
|
56
88
|
}
|
|
57
89
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
90
|
+
/* ── Loading state (matches portal full-page spinner) ── */
|
|
91
|
+
if (!initialLoaded && loading) {
|
|
92
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono 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: "Fragment" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-1", children: "NFT fractionalization protocol" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-8", children: (0, jsx_runtime_1.jsx)(IconLoader, { className: "w-5 h-5 animate-spin text-cyan-400" }) })] }));
|
|
93
|
+
}
|
|
94
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "max-w-7xl mx-auto font-mono space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-2xl font-bold text-white", children: "Fragment" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm mt-1", children: "NFT fractionalization protocol" })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: handleRefresh, disabled: refreshing, className: "flex items-center gap-1 px-3 py-1.5 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 hover:text-neutral-300 disabled:opacity-50 bg-transparent", children: [(0, jsx_runtime_1.jsx)(IconRefreshCw, { className: `w-4 h-4 ${refreshing ? 'animate-spin' : ''}` }), "Refresh"] })] }), actionError && ((0, jsx_runtime_1.jsxs)("div", { className: "bg-red-500/10 border border-red-500/20 rounded-lg p-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-red-500 mb-2", children: [(0, jsx_runtime_1.jsx)(IconAlertTriangle, { className: "w-5 h-5" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: actionError })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400 text-sm", children: "Please check the details and try again." })] })), actionSuccess && ((0, jsx_runtime_1.jsx)("div", { className: "p-3 bg-cyan-400/10 border border-cyan-400/30 rounded text-cyan-400 text-sm", children: actionSuccess })), (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-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-neutral-400 text-sm mb-4", children: [(0, jsx_runtime_1.jsx)(IconWallet, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsx)("span", { children: "MY_HOLDINGS" })] }), holdings && holdings.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: holdings.map((h, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "p-2 bg-cyan-400/20 rounded border border-cyan-400/30", children: (0, jsx_runtime_1.jsx)(IconPuzzle, { className: "h-5 w-5 text-cyan-400" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "font-bold text-white font-mono", children: ["Vault #", h.vault_id] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400", children: [(h.percentage ?? 0).toFixed(2), "% ownership"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-white font-mono", children: formatNumber(h.fragment_amount ?? 0, 0) }), (0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400", children: "fragments" })] })] }, `${h.vault_id}-${h.wallet ?? i}`))) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-8 text-neutral-400", children: [(0, jsx_runtime_1.jsx)(IconPuzzle, { className: "w-12 h-12 mx-auto mb-2 opacity-50" }), (0, jsx_runtime_1.jsx)("p", { children: "No fragment holdings" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm mt-1", children: "Purchase fragments from available vaults below" })] }))] }) }), (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-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between mb-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-neutral-400 text-sm", children: [(0, jsx_runtime_1.jsx)(IconImage, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsx)("span", { children: "FRAGMENT_VAULTS" })] }) }), vaults && vaults.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: vaults.map((v) => {
|
|
95
|
+
const soldPercentage = v.total_fragments > 0
|
|
96
|
+
? (v.fragments_sold / v.total_fragments) * 100
|
|
97
|
+
: 0;
|
|
98
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-start mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "p-2 bg-cyan-400/20 rounded border border-cyan-400/30", children: (0, jsx_runtime_1.jsx)(IconImage, { className: "h-6 w-6 text-cyan-400" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "font-bold text-white", children: [v.nft_type ?? 'Territory', " NFT"] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-xs text-neutral-400", children: [(v.nft_mint ?? '').slice(0, 8), "...", (v.nft_mint ?? '').slice(-4)] })] })] }), (0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 rounded text-xs ${v.is_active ? 'bg-white/20 text-white' : 'bg-neutral-700/50 text-neutral-400'}`, children: v.is_active ? 'OPEN' : 'CLOSED' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider", children: "total_fragments" }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-white font-mono", children: formatNumber(v.total_fragments ?? 0, 0) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider", children: "price_per_fragment" }), (0, jsx_runtime_1.jsxs)("div", { className: "text-lg font-bold text-cyan-400 font-mono", children: [formatMCC(v.price_per_fragment ?? 0), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider", children: "sold" }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-cyan-300 font-mono", children: formatNumber(v.fragments_sold ?? 0, 0) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-xs text-neutral-400 tracking-wider", children: "available" }), (0, jsx_runtime_1.jsx)("div", { className: "text-lg font-bold text-white font-mono", children: formatNumber((v.total_fragments ?? 0) - (v.fragments_sold ?? 0), 0) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-neutral-400 tracking-wider", children: "sale_progress" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-sm font-mono text-white", children: [soldPercentage.toFixed(1), "%"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full bg-neutral-800 rounded-full h-2", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-cyan-400 h-2 rounded-full transition-all", style: { width: `${Math.min(soldPercentage, 100)}%` } }) })] }), v.is_active && (v.fragments_sold ?? 0) < (v.total_fragments ?? 0) && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-end", children: (0, jsx_runtime_1.jsxs)("button", { onClick: () => {
|
|
99
|
+
setSelectedVault(v);
|
|
100
|
+
setBuyDialogOpen(true);
|
|
101
|
+
setActionError(null);
|
|
102
|
+
}, className: "flex items-center gap-1 px-4 py-2 text-sm bg-cyan-700 hover:bg-cyan-600 text-white rounded font-mono", children: [(0, jsx_runtime_1.jsx)(IconShoppingCart, { className: "w-4 h-4" }), "Buy Fragments"] }) }))] }, v.vault_id));
|
|
103
|
+
}) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "text-center py-8 text-neutral-400", children: [(0, jsx_runtime_1.jsx)(IconImage, { className: "w-12 h-12 mx-auto mb-2 opacity-50" }), (0, jsx_runtime_1.jsx)("p", { children: "No fragment vaults available" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm mt-1", children: "Check back later for new NFT fragmentation opportunities" })] }))] }) }), (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-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 text-neutral-400 text-sm mb-4", children: [(0, jsx_runtime_1.jsx)(IconInfo, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsx)("span", { children: "PROTOCOL_INFO" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4 text-sm", children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-medium text-white mb-2", children: "What is Fragmentation?" }), (0, jsx_runtime_1.jsx)("p", { className: "text-neutral-400", children: "Fragment allows NFT owners to split Territory NFTs into tradeable fragments, enabling shared ownership and community buyout mechanics." })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsx)("div", { className: "font-medium text-white mb-2", children: "Fragment Holder Rights" }), (0, jsx_runtime_1.jsxs)("ul", { className: "list-disc list-inside space-y-1 text-neutral-400", children: [(0, jsx_runtime_1.jsx)("li", { children: "Proportional ownership of the underlying NFT" }), (0, jsx_runtime_1.jsx)("li", { children: "Participate in buyout proposals" }), (0, jsx_runtime_1.jsx)("li", { children: "Trade fragments freely on the market" })] })] })] })] }) }), (0, jsx_runtime_1.jsx)(Modal, { open: buyDialogOpen, onClose: () => setBuyDialogOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-bold text-white", children: "Buy Fragments" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-neutral-400 mt-1", children: selectedVault
|
|
104
|
+
? `Purchase fragments from ${selectedVault.nft_type ?? 'Territory'} NFT vault`
|
|
105
|
+
: 'Select a vault' })] }), selectedVault && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Unit Price" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-cyan-400 font-bold font-mono", children: [formatMCC(selectedVault.price_per_fragment ?? 0), " MCC"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Available" }), (0, jsx_runtime_1.jsx)("span", { className: "text-white font-bold font-mono", children: formatNumber((selectedVault.total_fragments ?? 0) - (selectedVault.fragments_sold ?? 0), 0) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs text-neutral-400 tracking-wider", children: "purchase_amount" }), (0, jsx_runtime_1.jsx)("input", { type: "number", step: "1", min: "1", value: buyAmount, onChange: e => setBuyAmount(e.target.value), placeholder: "Enter amount", className: "w-full px-3 py-2 bg-neutral-800 border border-neutral-600 rounded text-white placeholder-neutral-400 outline-none focus:border-cyan-400" })] }), buyAmount && parseInt(buyAmount) > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "p-4 bg-neutral-800 rounded border border-neutral-700", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-neutral-400", children: "Total Price" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-white font-bold font-mono", children: [formatMCC((selectedVault.price_per_fragment ?? 0) * parseInt(buyAmount)), " MCC"] })] }) }))] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-3 pt-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => { setBuyDialogOpen(false); setBuyAmount(''); }, className: "px-4 py-2 text-sm border border-neutral-700 rounded text-neutral-400 hover:bg-neutral-800 hover:text-neutral-300 bg-transparent", children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleBuy, disabled: actionLoading || !buyAmount, className: "flex items-center gap-2 px-4 py-2 text-sm bg-cyan-700 hover:bg-cyan-600 text-white rounded disabled:opacity-50", children: actionLoading ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(IconLoader, { className: "h-4 w-4 animate-spin" }), "Buying..."] })) : ('Confirm Purchase') })] })] }) })] }));
|
|
62
106
|
}
|