@unicitylabs/sphere-ui 0.1.1 → 0.1.2
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/index.d.ts +61 -3
- package/dist/index.js +351 -163
- package/package.json +1 -1
- package/src/styles/tokens.css +14 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,67 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ButtonHTMLAttributes, ReactNode, InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes } from 'react';
|
|
3
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes } from 'react';
|
|
4
4
|
import { ColumnDef } from '@tanstack/react-table';
|
|
5
5
|
export { A as AchievementData, a as AchievementFormApi, Q as QueryKeys, b as QuestData, c as QuestFormApi, T as TrackData, d as TrackFormApi } from './index-DMHfA7fr.js';
|
|
6
6
|
|
|
7
|
+
interface DashboardLayoutProps {
|
|
8
|
+
/** Sidebar header — logo + app name */
|
|
9
|
+
logo: ReactNode;
|
|
10
|
+
/** Navigation content */
|
|
11
|
+
nav: ReactNode;
|
|
12
|
+
/** Footer content (e.g. sign out button) */
|
|
13
|
+
footer?: ReactNode;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Dashboard shell with sidebar + main content area.
|
|
18
|
+
* Used by sphere-backoffice and sphere-dev.
|
|
19
|
+
*/
|
|
20
|
+
declare function DashboardLayout({ logo, nav, footer, children }: DashboardLayoutProps): react_jsx_runtime.JSX.Element;
|
|
21
|
+
|
|
22
|
+
interface AppLogoProps {
|
|
23
|
+
/** Short code displayed in the icon (e.g. "SQ", "SD") */
|
|
24
|
+
icon?: string | ReactNode;
|
|
25
|
+
/** App title (e.g. "SPHERE QUESTS") */
|
|
26
|
+
title: string;
|
|
27
|
+
/** Subtitle (e.g. "ADMIN", "DEVELOPER") */
|
|
28
|
+
subtitle?: string;
|
|
29
|
+
/** Click handler (e.g. navigate to dashboard) */
|
|
30
|
+
onClick?: () => void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* App logo for dashboard sidebar.
|
|
34
|
+
* Orange icon + Anton title + Geist subtitle.
|
|
35
|
+
*/
|
|
36
|
+
declare function AppLogo({ icon, title, subtitle, onClick }: AppLogoProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
interface NavItem {
|
|
39
|
+
to: string;
|
|
40
|
+
label: string;
|
|
41
|
+
/** SVG path data for the icon (24x24 viewBox) */
|
|
42
|
+
icon?: string;
|
|
43
|
+
/** Custom icon element (overrides icon path) */
|
|
44
|
+
iconElement?: ReactNode;
|
|
45
|
+
/** Badge count (e.g. pending reviews) */
|
|
46
|
+
badge?: number;
|
|
47
|
+
}
|
|
48
|
+
interface NavGroup {
|
|
49
|
+
label?: string;
|
|
50
|
+
items: NavItem[];
|
|
51
|
+
}
|
|
52
|
+
interface SidebarNavProps {
|
|
53
|
+
groups: NavGroup[];
|
|
54
|
+
/** Current path for active state detection */
|
|
55
|
+
currentPath: string;
|
|
56
|
+
/** Called when a nav item is clicked */
|
|
57
|
+
onNavigate: (to: string) => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Sidebar navigation with grouped items, icons, and badges.
|
|
61
|
+
* Matches the admin panel sidebar style exactly.
|
|
62
|
+
*/
|
|
63
|
+
declare function SidebarNav({ groups, currentPath, onNavigate }: SidebarNavProps): react_jsx_runtime.JSX.Element;
|
|
64
|
+
|
|
7
65
|
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
8
66
|
error?: boolean;
|
|
9
67
|
}
|
|
@@ -196,4 +254,4 @@ declare const IconStar: (p: IconProps) => react_jsx_runtime.JSX.Element;
|
|
|
196
254
|
declare const IconDiamond: (p: IconProps) => react_jsx_runtime.JSX.Element;
|
|
197
255
|
declare const IconCircle: (p: IconProps) => react_jsx_runtime.JSX.Element;
|
|
198
256
|
|
|
199
|
-
export { AddressDisplay, AlertBanner, Button, type ButtonProps, type ButtonVariant, ChainInput, ConfirmDialog, CustomSelect, DataTable, EmptyState, Field, FormModal, IconArrowRight, IconBack, IconChain, IconCheck, IconChevronDown, IconChevronUp, IconChevronsDown, IconChevronsRight, IconCircle, IconDiamond, IconEdit, IconPlay, IconPlus, IconQuests, IconSearch, IconSettings, IconStar, IconTracks, IconTrash, IconUndo, IconX, Input, type InputProps, JsonPanel, JsonToggleButton, type MemoCondition, MemoConditionsEditor, PageShell, SearchInput, Section, Select, type SelectOption, type SelectProps, StatusBadge, Textarea, type TextareaProps, tagColor };
|
|
257
|
+
export { AddressDisplay, AlertBanner, AppLogo, Button, type ButtonProps, type ButtonVariant, ChainInput, ConfirmDialog, CustomSelect, DashboardLayout, DataTable, EmptyState, Field, FormModal, IconArrowRight, IconBack, IconChain, IconCheck, IconChevronDown, IconChevronUp, IconChevronsDown, IconChevronsRight, IconCircle, IconDiamond, IconEdit, IconPlay, IconPlus, IconQuests, IconSearch, IconSettings, IconStar, IconTracks, IconTrash, IconUndo, IconX, Input, type InputProps, JsonPanel, JsonToggleButton, type MemoCondition, MemoConditionsEditor, type NavGroup, type NavItem, PageShell, SearchInput, Section, Select, type SelectOption, type SelectProps, SidebarNav, StatusBadge, Textarea, type TextareaProps, tagColor };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,195 @@
|
|
|
1
|
+
// src/components/DashboardLayout.tsx
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Menu } from "lucide-react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function DashboardLayout({ logo, nav, footer, children }) {
|
|
6
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen flex", style: { background: "var(--bg-root)" }, children: [
|
|
8
|
+
mobileOpen && /* @__PURE__ */ jsx(
|
|
9
|
+
"div",
|
|
10
|
+
{
|
|
11
|
+
className: "lg:hidden fixed inset-0 bg-black/50 z-40",
|
|
12
|
+
onClick: () => setMobileOpen(false)
|
|
13
|
+
}
|
|
14
|
+
),
|
|
15
|
+
/* @__PURE__ */ jsxs(
|
|
16
|
+
"aside",
|
|
17
|
+
{
|
|
18
|
+
className: `fixed lg:static inset-y-0 left-0 z-50 w-56 shrink-0 flex flex-col relative transition-transform lg:translate-x-0 ${mobileOpen ? "translate-x-0" : "-translate-x-full"}`,
|
|
19
|
+
style: {
|
|
20
|
+
background: "linear-gradient(180deg, rgba(255,111,0,0.03) 0%, var(--bg-root) 40%)",
|
|
21
|
+
borderRight: "1px solid var(--border)"
|
|
22
|
+
},
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
className: "absolute top-0 left-0 right-0 h-px",
|
|
28
|
+
style: { background: "linear-gradient(90deg, transparent, var(--accent), transparent)" }
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
/* @__PURE__ */ jsx("div", { className: "px-5 py-5", style: { borderBottom: "1px solid var(--border)" }, children: logo }),
|
|
32
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 px-3 py-3 flex flex-col overflow-y-auto", children: nav }),
|
|
33
|
+
footer && /* @__PURE__ */ jsx("div", { className: "px-3 py-4", style: { borderTop: "1px solid var(--border)" }, children: footer })
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [
|
|
38
|
+
/* @__PURE__ */ jsx("div", { className: "lg:hidden flex items-center gap-3 p-4", style: { borderBottom: "1px solid var(--border)" }, children: /* @__PURE__ */ jsx(
|
|
39
|
+
"button",
|
|
40
|
+
{
|
|
41
|
+
onClick: () => setMobileOpen(true),
|
|
42
|
+
style: { color: "var(--text-muted)" },
|
|
43
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "w-5 h-5" })
|
|
44
|
+
}
|
|
45
|
+
) }),
|
|
46
|
+
/* @__PURE__ */ jsx("main", { className: "flex-1 overflow-auto", children })
|
|
47
|
+
] })
|
|
48
|
+
] });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/components/AppLogo.tsx
|
|
52
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
53
|
+
function AppLogo({ icon, title, subtitle, onClick }) {
|
|
54
|
+
const content = /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2.5", children: [
|
|
55
|
+
/* @__PURE__ */ jsx2(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: "w-8 h-8 rounded-lg flex items-center justify-center text-white text-xs relative",
|
|
59
|
+
style: {
|
|
60
|
+
background: "var(--accent)",
|
|
61
|
+
boxShadow: "0 0 16px rgba(255, 111, 0, 0.2)",
|
|
62
|
+
fontFamily: "var(--font-display)",
|
|
63
|
+
letterSpacing: "0.04em"
|
|
64
|
+
},
|
|
65
|
+
children: icon ?? title.slice(0, 2)
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
69
|
+
/* @__PURE__ */ jsx2(
|
|
70
|
+
"div",
|
|
71
|
+
{
|
|
72
|
+
className: "text-sm",
|
|
73
|
+
style: {
|
|
74
|
+
fontFamily: "var(--font-display)",
|
|
75
|
+
color: "var(--text-primary)",
|
|
76
|
+
letterSpacing: "0.04em",
|
|
77
|
+
textTransform: "uppercase"
|
|
78
|
+
},
|
|
79
|
+
children: title
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
subtitle && /* @__PURE__ */ jsx2(
|
|
83
|
+
"div",
|
|
84
|
+
{
|
|
85
|
+
className: "text-[10px] tracking-widest uppercase",
|
|
86
|
+
style: { color: "var(--text-muted)", fontFamily: "var(--font-body)" },
|
|
87
|
+
children: subtitle
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
] })
|
|
91
|
+
] });
|
|
92
|
+
if (onClick) {
|
|
93
|
+
return /* @__PURE__ */ jsx2("button", { onClick, className: "cursor-pointer text-left", children: content });
|
|
94
|
+
}
|
|
95
|
+
return content;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/components/SidebarNav.tsx
|
|
99
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
100
|
+
function SvgIcon({ d }) {
|
|
101
|
+
return /* @__PURE__ */ jsx3(
|
|
102
|
+
"svg",
|
|
103
|
+
{
|
|
104
|
+
width: "16",
|
|
105
|
+
height: "16",
|
|
106
|
+
className: "w-4 h-4 shrink-0",
|
|
107
|
+
viewBox: "0 0 24 24",
|
|
108
|
+
fill: "none",
|
|
109
|
+
stroke: "currentColor",
|
|
110
|
+
strokeWidth: "1.5",
|
|
111
|
+
strokeLinecap: "round",
|
|
112
|
+
strokeLinejoin: "round",
|
|
113
|
+
children: /* @__PURE__ */ jsx3("path", { d })
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
function SidebarNav({ groups, currentPath, onNavigate }) {
|
|
118
|
+
const isActive = (to) => {
|
|
119
|
+
if (to === "/") return currentPath === "/";
|
|
120
|
+
return currentPath === to || currentPath.startsWith(to + "/");
|
|
121
|
+
};
|
|
122
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: groups.map((group, gi) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
123
|
+
group.label && /* @__PURE__ */ jsx3(
|
|
124
|
+
"div",
|
|
125
|
+
{
|
|
126
|
+
className: "px-3 pt-5 pb-1.5",
|
|
127
|
+
style: {
|
|
128
|
+
fontFamily: "var(--font-body)",
|
|
129
|
+
fontSize: "0.6rem",
|
|
130
|
+
fontWeight: 600,
|
|
131
|
+
letterSpacing: "0.1em",
|
|
132
|
+
textTransform: "uppercase",
|
|
133
|
+
color: "var(--text-muted)"
|
|
134
|
+
},
|
|
135
|
+
children: group.label
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsx3("div", { className: "flex flex-col gap-0.5", children: group.items.map((item) => {
|
|
139
|
+
const active = isActive(item.to);
|
|
140
|
+
return /* @__PURE__ */ jsxs3(
|
|
141
|
+
"button",
|
|
142
|
+
{
|
|
143
|
+
onClick: () => onNavigate(item.to),
|
|
144
|
+
className: "flex items-center gap-3 px-3 py-2 rounded-lg text-[0.8125rem] transition-all w-full text-left",
|
|
145
|
+
style: active ? {
|
|
146
|
+
background: "var(--accent-glow)",
|
|
147
|
+
color: "var(--accent-text)",
|
|
148
|
+
fontWeight: 600,
|
|
149
|
+
fontFamily: "var(--font-body)",
|
|
150
|
+
boxShadow: "inset 2px 0 0 var(--accent)"
|
|
151
|
+
} : {
|
|
152
|
+
color: "var(--text-secondary)",
|
|
153
|
+
fontFamily: "var(--font-body)"
|
|
154
|
+
},
|
|
155
|
+
onMouseEnter: (e) => {
|
|
156
|
+
if (!active) {
|
|
157
|
+
e.currentTarget.style.background = "var(--bg-hover)";
|
|
158
|
+
e.currentTarget.style.color = "var(--text-primary)";
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
onMouseLeave: (e) => {
|
|
162
|
+
if (!active) {
|
|
163
|
+
e.currentTarget.style.background = "transparent";
|
|
164
|
+
e.currentTarget.style.color = "var(--text-secondary)";
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
children: [
|
|
168
|
+
item.iconElement ?? (item.icon && /* @__PURE__ */ jsx3(SvgIcon, { d: item.icon })),
|
|
169
|
+
item.label,
|
|
170
|
+
item.badge != null && item.badge > 0 && /* @__PURE__ */ jsx3(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
className: "ml-auto min-w-5 h-5 flex items-center justify-center rounded-full text-[10px] font-bold text-white px-1.5",
|
|
174
|
+
style: { background: "var(--accent)" },
|
|
175
|
+
children: item.badge
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
item.to
|
|
181
|
+
);
|
|
182
|
+
}) })
|
|
183
|
+
] }, gi)) });
|
|
184
|
+
}
|
|
185
|
+
|
|
1
186
|
// src/components/Input.tsx
|
|
2
187
|
import { forwardRef } from "react";
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
188
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4
189
|
var inputBase = "w-full px-4 py-2.5 bg-neutral-100 dark:bg-white/6 text-neutral-900 dark:text-white placeholder-neutral-400 dark:placeholder-white/25 rounded-xl border border-neutral-200 dark:border-white/8 focus:outline-none focus:border-orange-500 dark:focus:border-brand-orange transition-colors disabled:opacity-50";
|
|
5
190
|
var inputError = "border-red-400 dark:border-red-500/50 focus:border-red-500";
|
|
6
191
|
var Input = forwardRef(
|
|
7
|
-
({ className = "", error, ...props }, ref) => /* @__PURE__ */
|
|
192
|
+
({ className = "", error, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
8
193
|
"input",
|
|
9
194
|
{
|
|
10
195
|
ref,
|
|
@@ -15,7 +200,7 @@ var Input = forwardRef(
|
|
|
15
200
|
);
|
|
16
201
|
Input.displayName = "Input";
|
|
17
202
|
var Textarea = forwardRef(
|
|
18
|
-
({ className = "", error, ...props }, ref) => /* @__PURE__ */
|
|
203
|
+
({ className = "", error, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
19
204
|
"textarea",
|
|
20
205
|
{
|
|
21
206
|
ref,
|
|
@@ -26,7 +211,7 @@ var Textarea = forwardRef(
|
|
|
26
211
|
);
|
|
27
212
|
Textarea.displayName = "Textarea";
|
|
28
213
|
var Select = forwardRef(
|
|
29
|
-
({ className = "", error, children, ...props }, ref) => /* @__PURE__ */
|
|
214
|
+
({ className = "", error, children, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
30
215
|
"select",
|
|
31
216
|
{
|
|
32
217
|
ref,
|
|
@@ -48,7 +233,7 @@ var buttonVariants = {
|
|
|
48
233
|
ghost: "text-neutral-500 dark:text-white/45 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-white/6"
|
|
49
234
|
};
|
|
50
235
|
var Button = forwardRef(
|
|
51
|
-
({ variant = "primary", icon, children, className = "", disabled, ...props }, ref) => /* @__PURE__ */
|
|
236
|
+
({ variant = "primary", icon, children, className = "", disabled, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
52
237
|
"button",
|
|
53
238
|
{
|
|
54
239
|
ref,
|
|
@@ -65,21 +250,21 @@ var Button = forwardRef(
|
|
|
65
250
|
Button.displayName = "Button";
|
|
66
251
|
|
|
67
252
|
// src/components/Field.tsx
|
|
68
|
-
import { jsx as
|
|
253
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
69
254
|
function Field({ label, required, error, hint, className, children }) {
|
|
70
|
-
return /* @__PURE__ */
|
|
71
|
-
/* @__PURE__ */
|
|
255
|
+
return /* @__PURE__ */ jsxs5("div", { className, children: [
|
|
256
|
+
/* @__PURE__ */ jsxs5("label", { className: "text-xs block mb-1", style: { color: "var(--text-muted)" }, children: [
|
|
72
257
|
label,
|
|
73
|
-
required && /* @__PURE__ */
|
|
258
|
+
required && /* @__PURE__ */ jsx5("span", { className: "text-red-400 ml-0.5", children: "*" })
|
|
74
259
|
] }),
|
|
75
260
|
children,
|
|
76
|
-
hint && /* @__PURE__ */
|
|
77
|
-
error && /* @__PURE__ */
|
|
261
|
+
hint && /* @__PURE__ */ jsx5("p", { className: "text-[10px] mt-1", style: { color: "var(--text-muted)" }, children: hint }),
|
|
262
|
+
error && /* @__PURE__ */ jsx5("p", { className: "text-xs text-red-400 mt-1", children: error })
|
|
78
263
|
] });
|
|
79
264
|
}
|
|
80
265
|
function Section({ title, children }) {
|
|
81
|
-
return /* @__PURE__ */
|
|
82
|
-
/* @__PURE__ */
|
|
266
|
+
return /* @__PURE__ */ jsxs5("div", { children: [
|
|
267
|
+
/* @__PURE__ */ jsx5("h2", { className: "text-sm font-semibold mb-3 pb-2 border-b", style: { color: "var(--text-secondary)", borderColor: "var(--border)" }, children: title }),
|
|
83
268
|
children
|
|
84
269
|
] });
|
|
85
270
|
}
|
|
@@ -87,7 +272,7 @@ function Section({ title, children }) {
|
|
|
87
272
|
// src/components/FormModal.tsx
|
|
88
273
|
import { useEffect } from "react";
|
|
89
274
|
import { createPortal } from "react-dom";
|
|
90
|
-
import { jsx as
|
|
275
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
91
276
|
function FormModal({ title, isOpen, onClose, children, maxWidth = "max-w-lg" }) {
|
|
92
277
|
useEffect(() => {
|
|
93
278
|
if (!isOpen) return;
|
|
@@ -99,7 +284,7 @@ function FormModal({ title, isOpen, onClose, children, maxWidth = "max-w-lg" })
|
|
|
99
284
|
}, [isOpen, onClose]);
|
|
100
285
|
if (!isOpen) return null;
|
|
101
286
|
return createPortal(
|
|
102
|
-
/* @__PURE__ */
|
|
287
|
+
/* @__PURE__ */ jsx6("div", { className: "fixed inset-0 flex items-start justify-center z-50 p-4 overflow-y-auto", style: { background: "rgba(0,0,0,0.7)" }, children: /* @__PURE__ */ jsxs6(
|
|
103
288
|
"div",
|
|
104
289
|
{
|
|
105
290
|
className: `w-full ${maxWidth} mt-12 mb-12 animate-fade-in`,
|
|
@@ -111,9 +296,9 @@ function FormModal({ title, isOpen, onClose, children, maxWidth = "max-w-lg" })
|
|
|
111
296
|
padding: "1.5rem"
|
|
112
297
|
},
|
|
113
298
|
children: [
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
-
/* @__PURE__ */
|
|
299
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between mb-5", children: [
|
|
300
|
+
/* @__PURE__ */ jsx6("h2", { style: { fontFamily: "var(--font-display)", fontSize: "1.05rem", letterSpacing: "0.04em", color: "var(--text-primary)" }, children: title }),
|
|
301
|
+
/* @__PURE__ */ jsx6(
|
|
117
302
|
"button",
|
|
118
303
|
{
|
|
119
304
|
onClick: onClose,
|
|
@@ -136,7 +321,7 @@ function FormModal({ title, isOpen, onClose, children, maxWidth = "max-w-lg" })
|
|
|
136
321
|
// src/components/ConfirmDialog.tsx
|
|
137
322
|
import { useEffect as useEffect2 } from "react";
|
|
138
323
|
import { createPortal as createPortal2 } from "react-dom";
|
|
139
|
-
import { jsx as
|
|
324
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
140
325
|
function ConfirmDialog({
|
|
141
326
|
isOpen,
|
|
142
327
|
title,
|
|
@@ -156,12 +341,12 @@ function ConfirmDialog({
|
|
|
156
341
|
}, [isOpen, onCancel]);
|
|
157
342
|
if (!isOpen) return null;
|
|
158
343
|
return createPortal2(
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
161
|
-
/* @__PURE__ */
|
|
162
|
-
/* @__PURE__ */
|
|
163
|
-
/* @__PURE__ */
|
|
164
|
-
/* @__PURE__ */
|
|
344
|
+
/* @__PURE__ */ jsx7("div", { className: "fixed inset-0 flex items-center justify-center z-50 p-4", style: { background: "rgba(0,0,0,0.7)" }, children: /* @__PURE__ */ jsxs7("div", { className: "admin-card p-6 w-full max-w-sm animate-fade-in", children: [
|
|
345
|
+
/* @__PURE__ */ jsx7("h3", { className: "font-semibold text-white mb-2", children: title }),
|
|
346
|
+
/* @__PURE__ */ jsx7("p", { className: "text-sm mb-5", style: { color: "var(--text-muted)" }, children: message }),
|
|
347
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex gap-3", children: [
|
|
348
|
+
/* @__PURE__ */ jsx7("button", { onClick: onCancel, className: "btn-secondary flex-1", children: "Cancel" }),
|
|
349
|
+
/* @__PURE__ */ jsx7(
|
|
165
350
|
"button",
|
|
166
351
|
{
|
|
167
352
|
onClick: onConfirm,
|
|
@@ -176,7 +361,7 @@ function ConfirmDialog({
|
|
|
176
361
|
}
|
|
177
362
|
|
|
178
363
|
// src/components/StatusBadge.tsx
|
|
179
|
-
import { jsx as
|
|
364
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
180
365
|
var STATUS_COLORS = {
|
|
181
366
|
ACTIVE: "badge-green",
|
|
182
367
|
DRAFT: "badge-gray",
|
|
@@ -187,14 +372,14 @@ var STATUS_COLORS = {
|
|
|
187
372
|
REJECTED: "badge-red"
|
|
188
373
|
};
|
|
189
374
|
function StatusBadge({ status, className = "" }) {
|
|
190
|
-
return /* @__PURE__ */
|
|
375
|
+
return /* @__PURE__ */ jsx8("span", { className: `badge ${STATUS_COLORS[status] ?? "badge-gray"} ${className}`, children: status });
|
|
191
376
|
}
|
|
192
377
|
|
|
193
378
|
// src/components/SearchInput.tsx
|
|
194
|
-
import { jsx as
|
|
379
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
195
380
|
function SearchInput({ value, onChange, placeholder = "Search..." }) {
|
|
196
|
-
return /* @__PURE__ */
|
|
197
|
-
/* @__PURE__ */
|
|
381
|
+
return /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
382
|
+
/* @__PURE__ */ jsxs8(
|
|
198
383
|
"svg",
|
|
199
384
|
{
|
|
200
385
|
width: "16",
|
|
@@ -208,12 +393,12 @@ function SearchInput({ value, onChange, placeholder = "Search..." }) {
|
|
|
208
393
|
className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4",
|
|
209
394
|
style: { color: "var(--text-muted)" },
|
|
210
395
|
children: [
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
/* @__PURE__ */
|
|
396
|
+
/* @__PURE__ */ jsx9("circle", { cx: "11", cy: "11", r: "8" }),
|
|
397
|
+
/* @__PURE__ */ jsx9("path", { d: "m21 21-4.35-4.35" })
|
|
213
398
|
]
|
|
214
399
|
}
|
|
215
400
|
),
|
|
216
|
-
/* @__PURE__ */
|
|
401
|
+
/* @__PURE__ */ jsx9(
|
|
217
402
|
"input",
|
|
218
403
|
{
|
|
219
404
|
type: "text",
|
|
@@ -223,7 +408,7 @@ function SearchInput({ value, onChange, placeholder = "Search..." }) {
|
|
|
223
408
|
placeholder
|
|
224
409
|
}
|
|
225
410
|
),
|
|
226
|
-
value && /* @__PURE__ */
|
|
411
|
+
value && /* @__PURE__ */ jsx9(
|
|
227
412
|
"button",
|
|
228
413
|
{
|
|
229
414
|
onClick: () => onChange(""),
|
|
@@ -238,26 +423,26 @@ function SearchInput({ value, onChange, placeholder = "Search..." }) {
|
|
|
238
423
|
}
|
|
239
424
|
|
|
240
425
|
// src/components/EmptyState.tsx
|
|
241
|
-
import { jsx as
|
|
426
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
242
427
|
function EmptyState({ title, description, action }) {
|
|
243
|
-
return /* @__PURE__ */
|
|
244
|
-
/* @__PURE__ */
|
|
428
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
429
|
+
/* @__PURE__ */ jsx10(
|
|
245
430
|
"div",
|
|
246
431
|
{
|
|
247
432
|
className: "w-12 h-12 rounded-xl flex items-center justify-center mb-4",
|
|
248
433
|
style: { background: "var(--bg-elevated)", border: "1px solid var(--border)" },
|
|
249
|
-
children: /* @__PURE__ */
|
|
434
|
+
children: /* @__PURE__ */ jsx10("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { color: "var(--text-muted)" }, children: /* @__PURE__ */ jsx10("path", { d: "M20 13V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7m16 0v5a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-5m16 0h-2.586a1 1 0 0 0-.707.293l-2.414 2.414a1 1 0 0 1-.707.293h-3.172a1 1 0 0 1-.707-.293l-2.414-2.414A1 1 0 0 0 6.586 13H4" }) })
|
|
250
435
|
}
|
|
251
436
|
),
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
description && /* @__PURE__ */
|
|
437
|
+
/* @__PURE__ */ jsx10("div", { className: "text-sm font-medium mb-1", style: { color: "var(--text-secondary)" }, children: title }),
|
|
438
|
+
description && /* @__PURE__ */ jsx10("div", { className: "text-xs mb-4", style: { color: "var(--text-muted)" }, children: description }),
|
|
254
439
|
action
|
|
255
440
|
] });
|
|
256
441
|
}
|
|
257
442
|
|
|
258
443
|
// src/components/CustomSelect.tsx
|
|
259
|
-
import { useState, useRef, useEffect as useEffect3 } from "react";
|
|
260
|
-
import { jsx as
|
|
444
|
+
import { useState as useState2, useRef, useEffect as useEffect3 } from "react";
|
|
445
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
261
446
|
function CustomSelect({
|
|
262
447
|
options,
|
|
263
448
|
value,
|
|
@@ -266,7 +451,7 @@ function CustomSelect({
|
|
|
266
451
|
className = "",
|
|
267
452
|
size = "md"
|
|
268
453
|
}) {
|
|
269
|
-
const [open, setOpen] =
|
|
454
|
+
const [open, setOpen] = useState2(false);
|
|
270
455
|
const ref = useRef(null);
|
|
271
456
|
const selected = options.find((o) => o.value === value);
|
|
272
457
|
const label = selected?.label ?? placeholder ?? "Select...";
|
|
@@ -287,8 +472,8 @@ function CustomSelect({
|
|
|
287
472
|
return () => document.removeEventListener("keydown", handler);
|
|
288
473
|
}, [open]);
|
|
289
474
|
const textSize = size === "sm" ? "text-xs" : "text-sm";
|
|
290
|
-
return /* @__PURE__ */
|
|
291
|
-
/* @__PURE__ */
|
|
475
|
+
return /* @__PURE__ */ jsxs10("div", { ref, className: `relative ${className}`, children: [
|
|
476
|
+
/* @__PURE__ */ jsxs10(
|
|
292
477
|
"button",
|
|
293
478
|
{
|
|
294
479
|
type: "button",
|
|
@@ -296,8 +481,8 @@ function CustomSelect({
|
|
|
296
481
|
className: `admin-input w-full flex items-center justify-between gap-2 ${textSize} text-left`,
|
|
297
482
|
style: { color: selected ? "var(--text-primary)" : "var(--text-muted)" },
|
|
298
483
|
children: [
|
|
299
|
-
/* @__PURE__ */
|
|
300
|
-
/* @__PURE__ */
|
|
484
|
+
/* @__PURE__ */ jsx11("span", { className: "truncate", children: label }),
|
|
485
|
+
/* @__PURE__ */ jsx11(
|
|
301
486
|
"svg",
|
|
302
487
|
{
|
|
303
488
|
width: "12",
|
|
@@ -313,13 +498,13 @@ function CustomSelect({
|
|
|
313
498
|
color: "var(--text-muted)",
|
|
314
499
|
transform: open ? "rotate(180deg)" : "rotate(0deg)"
|
|
315
500
|
},
|
|
316
|
-
children: /* @__PURE__ */
|
|
501
|
+
children: /* @__PURE__ */ jsx11("path", { d: "M3 4.5L6 7.5L9 4.5" })
|
|
317
502
|
}
|
|
318
503
|
)
|
|
319
504
|
]
|
|
320
505
|
}
|
|
321
506
|
),
|
|
322
|
-
open && /* @__PURE__ */
|
|
507
|
+
open && /* @__PURE__ */ jsx11(
|
|
323
508
|
"div",
|
|
324
509
|
{
|
|
325
510
|
className: "absolute left-0 right-0 top-full mt-1 z-30 py-1 max-h-48 overflow-y-auto",
|
|
@@ -329,7 +514,7 @@ function CustomSelect({
|
|
|
329
514
|
borderRadius: "var(--radius-md)",
|
|
330
515
|
boxShadow: "0 8px 24px rgba(0,0,0,0.4)"
|
|
331
516
|
},
|
|
332
|
-
children: options.map((opt) => /* @__PURE__ */
|
|
517
|
+
children: options.map((opt) => /* @__PURE__ */ jsx11(
|
|
333
518
|
"button",
|
|
334
519
|
{
|
|
335
520
|
type: "button",
|
|
@@ -358,22 +543,22 @@ function CustomSelect({
|
|
|
358
543
|
}
|
|
359
544
|
|
|
360
545
|
// src/components/PageShell.tsx
|
|
361
|
-
import { jsx as
|
|
546
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
362
547
|
function PageShell({ title, subtitle, action, maxWidth, children }) {
|
|
363
|
-
return /* @__PURE__ */
|
|
364
|
-
/* @__PURE__ */
|
|
365
|
-
/* @__PURE__ */
|
|
366
|
-
/* @__PURE__ */
|
|
367
|
-
subtitle && /* @__PURE__ */
|
|
548
|
+
return /* @__PURE__ */ jsxs11("div", { className: `p-6 lg:p-8 ${maxWidth ?? ""}`, children: [
|
|
549
|
+
/* @__PURE__ */ jsxs11("div", { className: "page-header", children: [
|
|
550
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
551
|
+
/* @__PURE__ */ jsx12("h1", { className: "page-title", children: title }),
|
|
552
|
+
subtitle && /* @__PURE__ */ jsx12("p", { className: "page-subtitle", children: subtitle })
|
|
368
553
|
] }),
|
|
369
554
|
action
|
|
370
555
|
] }),
|
|
371
|
-
/* @__PURE__ */
|
|
556
|
+
/* @__PURE__ */ jsx12("div", { className: "animate-fade-in", children })
|
|
372
557
|
] });
|
|
373
558
|
}
|
|
374
559
|
|
|
375
560
|
// src/components/DataTable.tsx
|
|
376
|
-
import { useState as
|
|
561
|
+
import { useState as useState3, useMemo } from "react";
|
|
377
562
|
import {
|
|
378
563
|
useReactTable,
|
|
379
564
|
getCoreRowModel,
|
|
@@ -381,7 +566,7 @@ import {
|
|
|
381
566
|
getFilteredRowModel,
|
|
382
567
|
flexRender
|
|
383
568
|
} from "@tanstack/react-table";
|
|
384
|
-
import { jsx as
|
|
569
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
385
570
|
function DataTable({
|
|
386
571
|
columns,
|
|
387
572
|
data,
|
|
@@ -391,8 +576,8 @@ function DataTable({
|
|
|
391
576
|
enableSearch = true,
|
|
392
577
|
onRowClick
|
|
393
578
|
}) {
|
|
394
|
-
const [sorting, setSorting] =
|
|
395
|
-
const [globalFilter, setGlobalFilter] =
|
|
579
|
+
const [sorting, setSorting] = useState3([]);
|
|
580
|
+
const [globalFilter, setGlobalFilter] = useState3("");
|
|
396
581
|
const stableColumns = useMemo(() => columns, [columns]);
|
|
397
582
|
const table = useReactTable({
|
|
398
583
|
data,
|
|
@@ -405,10 +590,10 @@ function DataTable({
|
|
|
405
590
|
getFilteredRowModel: getFilteredRowModel()
|
|
406
591
|
});
|
|
407
592
|
if (isLoading) {
|
|
408
|
-
return /* @__PURE__ */
|
|
593
|
+
return /* @__PURE__ */ jsx13("div", { className: "py-12 text-center", style: { color: "var(--text-muted)" }, children: "Loading\u2026" });
|
|
409
594
|
}
|
|
410
|
-
return /* @__PURE__ */
|
|
411
|
-
enableSearch && /* @__PURE__ */
|
|
595
|
+
return /* @__PURE__ */ jsxs12("div", { children: [
|
|
596
|
+
enableSearch && /* @__PURE__ */ jsx13("div", { className: "mb-4 max-w-xs", children: /* @__PURE__ */ jsx13(
|
|
412
597
|
SearchInput,
|
|
413
598
|
{
|
|
414
599
|
value: globalFilter,
|
|
@@ -416,21 +601,21 @@ function DataTable({
|
|
|
416
601
|
placeholder: searchPlaceholder ?? "Search..."
|
|
417
602
|
}
|
|
418
603
|
) }),
|
|
419
|
-
table.getRowModel().rows.length === 0 ? /* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
604
|
+
table.getRowModel().rows.length === 0 ? /* @__PURE__ */ jsx13(EmptyState, { title: emptyMessage }) : /* @__PURE__ */ jsx13("div", { className: "admin-card overflow-hidden", children: /* @__PURE__ */ jsxs12("table", { className: "admin-table", children: [
|
|
605
|
+
/* @__PURE__ */ jsx13("thead", { children: table.getHeaderGroups().map((hg) => /* @__PURE__ */ jsx13("tr", { children: hg.headers.map((header) => /* @__PURE__ */ jsx13(
|
|
421
606
|
"th",
|
|
422
607
|
{
|
|
423
608
|
className: header.column.getCanSort() ? "cursor-pointer select-none" : "",
|
|
424
609
|
onClick: header.column.getToggleSortingHandler(),
|
|
425
|
-
children: /* @__PURE__ */
|
|
610
|
+
children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1", children: [
|
|
426
611
|
flexRender(header.column.columnDef.header, header.getContext()),
|
|
427
|
-
header.column.getIsSorted() === "asc" && /* @__PURE__ */
|
|
428
|
-
header.column.getIsSorted() === "desc" && /* @__PURE__ */
|
|
612
|
+
header.column.getIsSorted() === "asc" && /* @__PURE__ */ jsx13("span", { style: { color: "var(--accent-text)" }, children: "\u25B2" }),
|
|
613
|
+
header.column.getIsSorted() === "desc" && /* @__PURE__ */ jsx13("span", { style: { color: "var(--accent-text)" }, children: "\u25BC" })
|
|
429
614
|
] })
|
|
430
615
|
},
|
|
431
616
|
header.id
|
|
432
617
|
)) }, hg.id)) }),
|
|
433
|
-
/* @__PURE__ */
|
|
618
|
+
/* @__PURE__ */ jsx13("tbody", { children: table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx13(
|
|
434
619
|
"tr",
|
|
435
620
|
{
|
|
436
621
|
onClick: () => onRowClick?.(row.original),
|
|
@@ -442,7 +627,7 @@ function DataTable({
|
|
|
442
627
|
onMouseLeave: (e) => {
|
|
443
628
|
if (onRowClick) e.currentTarget.style.background = "";
|
|
444
629
|
},
|
|
445
|
-
children: row.getVisibleCells().map((cell) => /* @__PURE__ */
|
|
630
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx13("td", { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
|
|
446
631
|
},
|
|
447
632
|
row.id
|
|
448
633
|
)) })
|
|
@@ -451,7 +636,7 @@ function DataTable({
|
|
|
451
636
|
}
|
|
452
637
|
|
|
453
638
|
// src/components/AlertBanner.tsx
|
|
454
|
-
import { jsx as
|
|
639
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
455
640
|
var STYLES = {
|
|
456
641
|
warning: {
|
|
457
642
|
bg: "rgba(251,191,36,0.06)",
|
|
@@ -468,16 +653,16 @@ var STYLES = {
|
|
|
468
653
|
};
|
|
469
654
|
function AlertBanner({ type, title, children }) {
|
|
470
655
|
const s = STYLES[type];
|
|
471
|
-
return /* @__PURE__ */
|
|
656
|
+
return /* @__PURE__ */ jsx14(
|
|
472
657
|
"div",
|
|
473
658
|
{
|
|
474
659
|
className: "rounded-lg p-3 text-sm",
|
|
475
660
|
style: { background: s.bg, border: `1px solid ${s.border}` },
|
|
476
|
-
children: /* @__PURE__ */
|
|
477
|
-
/* @__PURE__ */
|
|
478
|
-
/* @__PURE__ */
|
|
479
|
-
/* @__PURE__ */
|
|
480
|
-
/* @__PURE__ */
|
|
661
|
+
children: /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-2", children: [
|
|
662
|
+
/* @__PURE__ */ jsx14("span", { className: "flex-shrink-0 text-sm leading-5", children: s.icon }),
|
|
663
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
664
|
+
/* @__PURE__ */ jsx14("div", { className: "font-medium text-xs mb-0.5", style: { color: s.titleColor }, children: title }),
|
|
665
|
+
/* @__PURE__ */ jsx14("div", { style: { color: "var(--text-muted)", fontSize: "0.75rem", lineHeight: "1.4" }, children })
|
|
481
666
|
] })
|
|
482
667
|
] })
|
|
483
668
|
}
|
|
@@ -485,8 +670,8 @@ function AlertBanner({ type, title, children }) {
|
|
|
485
670
|
}
|
|
486
671
|
|
|
487
672
|
// src/components/AddressDisplay.tsx
|
|
488
|
-
import { useState as
|
|
489
|
-
import { Fragment, jsx as
|
|
673
|
+
import { useState as useState4, useCallback } from "react";
|
|
674
|
+
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
490
675
|
function truncateAddress(address) {
|
|
491
676
|
const prefix = "DIRECT://";
|
|
492
677
|
if (address.startsWith(prefix)) {
|
|
@@ -501,7 +686,7 @@ function truncateAddress(address) {
|
|
|
501
686
|
return address;
|
|
502
687
|
}
|
|
503
688
|
function AddressDisplay({ address, nametag, truncate = true }) {
|
|
504
|
-
const [copied, setCopied] =
|
|
689
|
+
const [copied, setCopied] = useState4(false);
|
|
505
690
|
const handleCopy = useCallback(() => {
|
|
506
691
|
navigator.clipboard.writeText(address).then(() => {
|
|
507
692
|
setCopied(true);
|
|
@@ -509,13 +694,13 @@ function AddressDisplay({ address, nametag, truncate = true }) {
|
|
|
509
694
|
});
|
|
510
695
|
}, [address]);
|
|
511
696
|
const displayAddress = truncate ? truncateAddress(address) : address;
|
|
512
|
-
return /* @__PURE__ */
|
|
513
|
-
/* @__PURE__ */
|
|
514
|
-
/* @__PURE__ */
|
|
697
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-1.5 min-w-0", children: [
|
|
698
|
+
/* @__PURE__ */ jsx15("div", { className: "min-w-0 flex-1", children: nametag ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
699
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-sm font-medium", style: { color: "var(--text-primary)" }, children: [
|
|
515
700
|
"@",
|
|
516
701
|
nametag
|
|
517
702
|
] }),
|
|
518
|
-
/* @__PURE__ */
|
|
703
|
+
/* @__PURE__ */ jsx15(
|
|
519
704
|
"div",
|
|
520
705
|
{
|
|
521
706
|
className: "text-[11px] font-mono truncate",
|
|
@@ -524,7 +709,7 @@ function AddressDisplay({ address, nametag, truncate = true }) {
|
|
|
524
709
|
children: displayAddress
|
|
525
710
|
}
|
|
526
711
|
)
|
|
527
|
-
] }) : /* @__PURE__ */
|
|
712
|
+
] }) : /* @__PURE__ */ jsx15(
|
|
528
713
|
"div",
|
|
529
714
|
{
|
|
530
715
|
className: "text-xs font-mono truncate",
|
|
@@ -533,7 +718,7 @@ function AddressDisplay({ address, nametag, truncate = true }) {
|
|
|
533
718
|
children: displayAddress
|
|
534
719
|
}
|
|
535
720
|
) }),
|
|
536
|
-
/* @__PURE__ */
|
|
721
|
+
/* @__PURE__ */ jsx15(
|
|
537
722
|
"button",
|
|
538
723
|
{
|
|
539
724
|
onClick: handleCopy,
|
|
@@ -546,9 +731,9 @@ function AddressDisplay({ address, nametag, truncate = true }) {
|
|
|
546
731
|
if (!copied) e.currentTarget.style.color = "var(--text-muted)";
|
|
547
732
|
},
|
|
548
733
|
title: copied ? "Copied!" : "Copy address",
|
|
549
|
-
children: copied ? /* @__PURE__ */
|
|
550
|
-
/* @__PURE__ */
|
|
551
|
-
/* @__PURE__ */
|
|
734
|
+
children: copied ? /* @__PURE__ */ jsx15("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx15("path", { d: "M20 6L9 17l-5-5" }) }) : /* @__PURE__ */ jsxs14("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
735
|
+
/* @__PURE__ */ jsx15("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
736
|
+
/* @__PURE__ */ jsx15("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
552
737
|
] })
|
|
553
738
|
}
|
|
554
739
|
)
|
|
@@ -556,17 +741,17 @@ function AddressDisplay({ address, nametag, truncate = true }) {
|
|
|
556
741
|
}
|
|
557
742
|
|
|
558
743
|
// src/components/JsonPanel.tsx
|
|
559
|
-
import { useState as
|
|
560
|
-
import { jsx as
|
|
744
|
+
import { useState as useState5, useEffect as useEffect4, useRef as useRef2, useCallback as useCallback2 } from "react";
|
|
745
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
561
746
|
function JsonPanel({
|
|
562
747
|
value,
|
|
563
748
|
onChange,
|
|
564
749
|
excludeKeys = [],
|
|
565
750
|
title = "JSON"
|
|
566
751
|
}) {
|
|
567
|
-
const [text, setText] =
|
|
568
|
-
const [parseError, setParseError] =
|
|
569
|
-
const [isEditing, setIsEditing] =
|
|
752
|
+
const [text, setText] = useState5("");
|
|
753
|
+
const [parseError, setParseError] = useState5(null);
|
|
754
|
+
const [isEditing, setIsEditing] = useState5(false);
|
|
570
755
|
const textareaRef = useRef2(null);
|
|
571
756
|
useEffect4(() => {
|
|
572
757
|
if (isEditing) return;
|
|
@@ -590,24 +775,24 @@ function JsonPanel({
|
|
|
590
775
|
}, [onChange]);
|
|
591
776
|
const handleFocus = useCallback2(() => setIsEditing(true), []);
|
|
592
777
|
const handleBlur = useCallback2(() => setIsEditing(false), []);
|
|
593
|
-
const [copied, setCopied] =
|
|
778
|
+
const [copied, setCopied] = useState5(false);
|
|
594
779
|
const handleCopy = useCallback2(async () => {
|
|
595
780
|
await navigator.clipboard.writeText(text);
|
|
596
781
|
setCopied(true);
|
|
597
782
|
setTimeout(() => setCopied(false), 1500);
|
|
598
783
|
}, [text]);
|
|
599
784
|
const lineCount = text.split("\n").length;
|
|
600
|
-
return /* @__PURE__ */
|
|
601
|
-
/* @__PURE__ */
|
|
602
|
-
/* @__PURE__ */
|
|
603
|
-
/* @__PURE__ */
|
|
785
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col h-full", style: { minWidth: 320 }, children: [
|
|
786
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between px-3 py-2", style: { borderBottom: "1px solid var(--border)" }, children: [
|
|
787
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
788
|
+
/* @__PURE__ */ jsxs15("span", { className: "text-xs font-mono font-semibold", style: { color: "var(--text-muted)" }, children: [
|
|
604
789
|
"{ }",
|
|
605
790
|
" ",
|
|
606
791
|
title
|
|
607
792
|
] }),
|
|
608
|
-
parseError && /* @__PURE__ */
|
|
793
|
+
parseError && /* @__PURE__ */ jsx16("span", { className: "text-[10px] px-1.5 py-0.5 rounded", style: { background: "rgba(239,68,68,0.1)", color: "#f87171" }, children: "Error" })
|
|
609
794
|
] }),
|
|
610
|
-
/* @__PURE__ */
|
|
795
|
+
/* @__PURE__ */ jsx16(
|
|
611
796
|
"button",
|
|
612
797
|
{
|
|
613
798
|
onClick: handleCopy,
|
|
@@ -628,8 +813,8 @@ function JsonPanel({
|
|
|
628
813
|
}
|
|
629
814
|
)
|
|
630
815
|
] }),
|
|
631
|
-
/* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
816
|
+
/* @__PURE__ */ jsx16("div", { className: "flex-1 relative overflow-hidden", children: /* @__PURE__ */ jsxs15("div", { className: "absolute inset-0 flex overflow-auto", children: [
|
|
817
|
+
/* @__PURE__ */ jsx16(
|
|
633
818
|
"div",
|
|
634
819
|
{
|
|
635
820
|
className: "shrink-0 text-right pr-2 pt-3 select-none",
|
|
@@ -643,10 +828,10 @@ function JsonPanel({
|
|
|
643
828
|
background: "var(--bg-surface)",
|
|
644
829
|
borderRight: "1px solid var(--border)"
|
|
645
830
|
},
|
|
646
|
-
children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */
|
|
831
|
+
children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */ jsx16("div", { children: i + 1 }, i))
|
|
647
832
|
}
|
|
648
833
|
),
|
|
649
|
-
/* @__PURE__ */
|
|
834
|
+
/* @__PURE__ */ jsx16(
|
|
650
835
|
"textarea",
|
|
651
836
|
{
|
|
652
837
|
ref: textareaRef,
|
|
@@ -668,11 +853,11 @@ function JsonPanel({
|
|
|
668
853
|
}
|
|
669
854
|
)
|
|
670
855
|
] }) }),
|
|
671
|
-
parseError && /* @__PURE__ */
|
|
856
|
+
parseError && /* @__PURE__ */ jsx16("div", { className: "px-3 py-1.5 text-[10px]", style: { background: "rgba(239,68,68,0.06)", color: "#f87171", borderTop: "1px solid rgba(239,68,68,0.15)" }, children: parseError })
|
|
672
857
|
] });
|
|
673
858
|
}
|
|
674
859
|
function JsonToggleButton({ active, onClick }) {
|
|
675
|
-
return /* @__PURE__ */
|
|
860
|
+
return /* @__PURE__ */ jsx16(
|
|
676
861
|
"button",
|
|
677
862
|
{
|
|
678
863
|
onClick,
|
|
@@ -703,8 +888,8 @@ function JsonToggleButton({ active, onClick }) {
|
|
|
703
888
|
}
|
|
704
889
|
|
|
705
890
|
// src/components/ChainInput.tsx
|
|
706
|
-
import { useState as
|
|
707
|
-
import { jsx as
|
|
891
|
+
import { useState as useState6, useId } from "react";
|
|
892
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
708
893
|
var TAG_PALETTES = [
|
|
709
894
|
{ bg: "rgba(16, 185, 129, 0.12)", color: "#34d399", border: "rgba(16, 185, 129, 0.2)" },
|
|
710
895
|
{ bg: "rgba(59, 130, 246, 0.12)", color: "#60a5fa", border: "rgba(59, 130, 246, 0.2)" },
|
|
@@ -723,8 +908,8 @@ function tagColor(tag) {
|
|
|
723
908
|
return TAG_PALETTES[Math.abs(hash) % TAG_PALETTES.length];
|
|
724
909
|
}
|
|
725
910
|
function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
726
|
-
const [input, setInput] =
|
|
727
|
-
const [open, setOpen] =
|
|
911
|
+
const [input, setInput] = useState6("");
|
|
912
|
+
const [open, setOpen] = useState6(false);
|
|
728
913
|
const inputId = useId();
|
|
729
914
|
const entries = Object.entries(chains);
|
|
730
915
|
const available = suggestions.filter((s) => !(s in chains) && (!input || s.toLowerCase().includes(input.toLowerCase())));
|
|
@@ -758,8 +943,8 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
758
943
|
const isSm = size === "sm";
|
|
759
944
|
const textSize = isSm ? "text-[0.6rem]" : "text-[0.65rem]";
|
|
760
945
|
const minH = isSm ? "min-h-[32px]" : "min-h-[38px]";
|
|
761
|
-
return /* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
946
|
+
return /* @__PURE__ */ jsxs16("div", { className: "relative", children: [
|
|
947
|
+
/* @__PURE__ */ jsxs16(
|
|
763
948
|
"div",
|
|
764
949
|
{
|
|
765
950
|
className: `admin-input flex flex-wrap gap-1.5 !p-1.5 ${minH} cursor-text`,
|
|
@@ -767,14 +952,14 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
767
952
|
children: [
|
|
768
953
|
entries.map(([name, order]) => {
|
|
769
954
|
const c = tagColor(name);
|
|
770
|
-
return /* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ jsxs16(
|
|
771
956
|
"span",
|
|
772
957
|
{
|
|
773
958
|
className: `inline-flex items-center gap-1 ${textSize} font-semibold px-2 py-0.5 rounded`,
|
|
774
959
|
style: { background: c.bg, color: c.color, border: `1px solid ${c.border}` },
|
|
775
960
|
children: [
|
|
776
961
|
name,
|
|
777
|
-
/* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsx17(
|
|
778
963
|
"input",
|
|
779
964
|
{
|
|
780
965
|
type: "number",
|
|
@@ -786,7 +971,7 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
786
971
|
onClick: (e) => e.stopPropagation()
|
|
787
972
|
}
|
|
788
973
|
),
|
|
789
|
-
/* @__PURE__ */
|
|
974
|
+
/* @__PURE__ */ jsx17(
|
|
790
975
|
"button",
|
|
791
976
|
{
|
|
792
977
|
type: "button",
|
|
@@ -803,7 +988,7 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
803
988
|
name
|
|
804
989
|
);
|
|
805
990
|
}),
|
|
806
|
-
/* @__PURE__ */
|
|
991
|
+
/* @__PURE__ */ jsx17(
|
|
807
992
|
"input",
|
|
808
993
|
{
|
|
809
994
|
id: inputId,
|
|
@@ -823,13 +1008,13 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
823
1008
|
]
|
|
824
1009
|
}
|
|
825
1010
|
),
|
|
826
|
-
open && (available.length > 0 || isNew) && /* @__PURE__ */
|
|
1011
|
+
open && (available.length > 0 || isNew) && /* @__PURE__ */ jsxs16(
|
|
827
1012
|
"div",
|
|
828
1013
|
{
|
|
829
1014
|
className: "absolute left-0 right-0 top-full mt-1 z-20 py-1 max-h-40 overflow-y-auto",
|
|
830
1015
|
style: { background: "var(--bg-elevated)", border: "1px solid var(--border)", borderRadius: "var(--radius-md)" },
|
|
831
1016
|
children: [
|
|
832
|
-
isNew && /* @__PURE__ */
|
|
1017
|
+
isNew && /* @__PURE__ */ jsxs16(
|
|
833
1018
|
"button",
|
|
834
1019
|
{
|
|
835
1020
|
onMouseDown: () => addChain(trimmed),
|
|
@@ -850,7 +1035,7 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
850
1035
|
),
|
|
851
1036
|
available.map((s) => {
|
|
852
1037
|
const c = tagColor(s);
|
|
853
|
-
return /* @__PURE__ */
|
|
1038
|
+
return /* @__PURE__ */ jsxs16(
|
|
854
1039
|
"button",
|
|
855
1040
|
{
|
|
856
1041
|
onMouseDown: () => addChain(s),
|
|
@@ -863,7 +1048,7 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
863
1048
|
e.currentTarget.style.background = "transparent";
|
|
864
1049
|
},
|
|
865
1050
|
children: [
|
|
866
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx17("span", { className: "w-2 h-2 rounded-full flex-shrink-0", style: { background: c.color } }),
|
|
867
1052
|
s
|
|
868
1053
|
]
|
|
869
1054
|
},
|
|
@@ -877,7 +1062,7 @@ function ChainInput({ chains, suggestions, onChange, size = "md" }) {
|
|
|
877
1062
|
}
|
|
878
1063
|
|
|
879
1064
|
// src/components/MemoConditionsEditor.tsx
|
|
880
|
-
import { Fragment as
|
|
1065
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
881
1066
|
var MEMO_OPERATORS = [
|
|
882
1067
|
{ value: "eq", label: "Equals (=)", values: 1 },
|
|
883
1068
|
{ value: "neq", label: "Not equals (\u2260)", values: 1 },
|
|
@@ -923,16 +1108,16 @@ function MemoConditionsEditor({ conditions, onChange }) {
|
|
|
923
1108
|
const remove = (i) => onChange(conditions.filter((_, idx) => idx !== i));
|
|
924
1109
|
const update = (i, patch) => onChange(conditions.map((c, idx) => idx === i ? { ...c, ...patch } : c));
|
|
925
1110
|
const opMeta = (op) => MEMO_OPERATORS.find((o) => o.value === op) ?? MEMO_OPERATORS[0];
|
|
926
|
-
return /* @__PURE__ */
|
|
927
|
-
/* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
/* @__PURE__ */
|
|
1111
|
+
return /* @__PURE__ */ jsxs17("div", { children: [
|
|
1112
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
1113
|
+
/* @__PURE__ */ jsx18("span", { className: "text-xs font-medium", style: { color: "var(--text-muted)" }, children: "Memo Conditions" }),
|
|
1114
|
+
/* @__PURE__ */ jsx18("button", { type: "button", onClick: add, className: "text-[10px] px-2 py-0.5 rounded cursor-pointer", style: { background: "var(--bg-elevated)", color: "var(--accent-text)" }, children: "+ Add" })
|
|
930
1115
|
] }),
|
|
931
|
-
conditions.length > 0 ? /* @__PURE__ */
|
|
1116
|
+
conditions.length > 0 ? /* @__PURE__ */ jsx18("div", { className: "flex flex-col gap-2", children: conditions.map((cond, i) => {
|
|
932
1117
|
const meta = opMeta(cond.operator);
|
|
933
|
-
return /* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsxs17("div", { className: "rounded-lg p-2.5", style: { background: "rgba(255,255,255,0.02)", border: "1px solid var(--border)" }, children: [
|
|
1119
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex gap-2 items-center", children: [
|
|
1120
|
+
/* @__PURE__ */ jsx18(
|
|
936
1121
|
"input",
|
|
937
1122
|
{
|
|
938
1123
|
className: "admin-input flex-1 text-xs",
|
|
@@ -941,7 +1126,7 @@ function MemoConditionsEditor({ conditions, onChange }) {
|
|
|
941
1126
|
onChange: (e) => update(i, { key: e.target.value })
|
|
942
1127
|
}
|
|
943
1128
|
),
|
|
944
|
-
/* @__PURE__ */
|
|
1129
|
+
/* @__PURE__ */ jsx18(
|
|
945
1130
|
CustomSelect,
|
|
946
1131
|
{
|
|
947
1132
|
size: "sm",
|
|
@@ -951,7 +1136,7 @@ function MemoConditionsEditor({ conditions, onChange }) {
|
|
|
951
1136
|
options: MEMO_OPERATORS.map((o) => ({ value: o.value, label: o.label }))
|
|
952
1137
|
}
|
|
953
1138
|
),
|
|
954
|
-
meta.values >= 1 && /* @__PURE__ */
|
|
1139
|
+
meta.values >= 1 && /* @__PURE__ */ jsx18(
|
|
955
1140
|
"input",
|
|
956
1141
|
{
|
|
957
1142
|
className: "admin-input flex-1 text-xs",
|
|
@@ -960,9 +1145,9 @@ function MemoConditionsEditor({ conditions, onChange }) {
|
|
|
960
1145
|
onChange: (e) => update(i, { value: e.target.value })
|
|
961
1146
|
}
|
|
962
1147
|
),
|
|
963
|
-
meta.values === 2 && /* @__PURE__ */
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
/* @__PURE__ */
|
|
1148
|
+
meta.values === 2 && /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
1149
|
+
/* @__PURE__ */ jsx18("span", { className: "text-[10px]", style: { color: "var(--text-muted)" }, children: "and" }),
|
|
1150
|
+
/* @__PURE__ */ jsx18(
|
|
966
1151
|
"input",
|
|
967
1152
|
{
|
|
968
1153
|
className: "admin-input flex-1 text-xs",
|
|
@@ -972,18 +1157,18 @@ function MemoConditionsEditor({ conditions, onChange }) {
|
|
|
972
1157
|
}
|
|
973
1158
|
)
|
|
974
1159
|
] }),
|
|
975
|
-
/* @__PURE__ */
|
|
1160
|
+
/* @__PURE__ */ jsx18("button", { type: "button", onClick: () => remove(i), className: "text-red-400 text-sm px-1 cursor-pointer", children: "\xD7" })
|
|
976
1161
|
] }),
|
|
977
|
-
/* @__PURE__ */
|
|
1162
|
+
/* @__PURE__ */ jsx18("p", { className: "text-[10px] mt-1.5 ml-0.5", style: { color: "var(--text-muted)", fontStyle: "italic" }, children: conditionPreview(cond) })
|
|
978
1163
|
] }, i);
|
|
979
|
-
}) }) : /* @__PURE__ */
|
|
1164
|
+
}) }) : /* @__PURE__ */ jsx18("p", { className: "text-[10px]", style: { color: "var(--text-muted)" }, children: 'No conditions \u2014 matches any memo transaction. Click "+ Add" to filter.' })
|
|
980
1165
|
] });
|
|
981
1166
|
}
|
|
982
1167
|
|
|
983
1168
|
// src/components/Icons.tsx
|
|
984
|
-
import { jsx as
|
|
1169
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
985
1170
|
function I({ d, size = 16, className, style }) {
|
|
986
|
-
return /* @__PURE__ */
|
|
1171
|
+
return /* @__PURE__ */ jsx19(
|
|
987
1172
|
"svg",
|
|
988
1173
|
{
|
|
989
1174
|
width: size,
|
|
@@ -996,7 +1181,7 @@ function I({ d, size = 16, className, style }) {
|
|
|
996
1181
|
strokeLinejoin: "round",
|
|
997
1182
|
className,
|
|
998
1183
|
style,
|
|
999
|
-
children: /* @__PURE__ */
|
|
1184
|
+
children: /* @__PURE__ */ jsx19("path", { d })
|
|
1000
1185
|
}
|
|
1001
1186
|
);
|
|
1002
1187
|
}
|
|
@@ -1028,34 +1213,36 @@ var P = {
|
|
|
1028
1213
|
diamond: "M2.7 10.3a2.41 2.41 0 0 0 0 3.41l7.59 7.59a2.41 2.41 0 0 0 3.41 0l7.59-7.59a2.41 2.41 0 0 0 0-3.41L13.7 2.71a2.41 2.41 0 0 0-3.41 0L2.7 10.3z",
|
|
1029
1214
|
circle: "M12 12m-4 0a4 4 0 1 0 8 0 4 4 0 1 0-8 0"
|
|
1030
1215
|
};
|
|
1031
|
-
var IconBack = (p) => /* @__PURE__ */
|
|
1032
|
-
var IconUndo = (p) => /* @__PURE__ */
|
|
1033
|
-
var IconQuests = (p) => /* @__PURE__ */
|
|
1034
|
-
var IconTracks = (p) => /* @__PURE__ */
|
|
1035
|
-
var IconSettings = (p) => /* @__PURE__ */
|
|
1036
|
-
var IconChain = (p) => /* @__PURE__ */
|
|
1037
|
-
var IconPlus = (p) => /* @__PURE__ */
|
|
1038
|
-
var IconEdit = (p) => /* @__PURE__ */
|
|
1039
|
-
var IconTrash = (p) => /* @__PURE__ */
|
|
1040
|
-
var IconX = (p) => /* @__PURE__ */
|
|
1041
|
-
var IconCheck = (p) => /* @__PURE__ */
|
|
1042
|
-
var IconSearch = (p) => /* @__PURE__ */
|
|
1043
|
-
var IconChevronUp = (p) => /* @__PURE__ */
|
|
1044
|
-
var IconChevronDown = (p) => /* @__PURE__ */
|
|
1045
|
-
var IconChevronsDown = (p) => /* @__PURE__ */
|
|
1046
|
-
var IconChevronsRight = (p) => /* @__PURE__ */
|
|
1047
|
-
var IconArrowRight = (p) => /* @__PURE__ */
|
|
1048
|
-
var IconPlay = (p) => /* @__PURE__ */
|
|
1049
|
-
var IconStar = (p) => /* @__PURE__ */
|
|
1050
|
-
var IconDiamond = (p) => /* @__PURE__ */
|
|
1051
|
-
var IconCircle = (p) => /* @__PURE__ */
|
|
1216
|
+
var IconBack = (p) => /* @__PURE__ */ jsx19(I, { d: P.back, ...p });
|
|
1217
|
+
var IconUndo = (p) => /* @__PURE__ */ jsx19(I, { d: P.undo, ...p });
|
|
1218
|
+
var IconQuests = (p) => /* @__PURE__ */ jsx19(I, { d: P.quests, ...p });
|
|
1219
|
+
var IconTracks = (p) => /* @__PURE__ */ jsx19(I, { d: P.tracks, ...p });
|
|
1220
|
+
var IconSettings = (p) => /* @__PURE__ */ jsx19(I, { d: P.settings, ...p });
|
|
1221
|
+
var IconChain = (p) => /* @__PURE__ */ jsx19(I, { d: P.chain, ...p });
|
|
1222
|
+
var IconPlus = (p) => /* @__PURE__ */ jsx19(I, { d: P.plus, ...p });
|
|
1223
|
+
var IconEdit = (p) => /* @__PURE__ */ jsx19(I, { d: P.edit, ...p });
|
|
1224
|
+
var IconTrash = (p) => /* @__PURE__ */ jsx19(I, { d: P.trash, ...p });
|
|
1225
|
+
var IconX = (p) => /* @__PURE__ */ jsx19(I, { d: P.x, ...p });
|
|
1226
|
+
var IconCheck = (p) => /* @__PURE__ */ jsx19(I, { d: P.check, ...p });
|
|
1227
|
+
var IconSearch = (p) => /* @__PURE__ */ jsx19(I, { d: P.search, ...p });
|
|
1228
|
+
var IconChevronUp = (p) => /* @__PURE__ */ jsx19(I, { d: P.chevronUp, ...p });
|
|
1229
|
+
var IconChevronDown = (p) => /* @__PURE__ */ jsx19(I, { d: P.chevronDown, ...p });
|
|
1230
|
+
var IconChevronsDown = (p) => /* @__PURE__ */ jsx19(I, { d: P.chevronsDown, ...p });
|
|
1231
|
+
var IconChevronsRight = (p) => /* @__PURE__ */ jsx19(I, { d: P.chevronsRight, ...p });
|
|
1232
|
+
var IconArrowRight = (p) => /* @__PURE__ */ jsx19(I, { d: P.arrowRight, ...p });
|
|
1233
|
+
var IconPlay = (p) => /* @__PURE__ */ jsx19(I, { d: P.play, ...p });
|
|
1234
|
+
var IconStar = (p) => /* @__PURE__ */ jsx19(I, { d: P.star, ...p });
|
|
1235
|
+
var IconDiamond = (p) => /* @__PURE__ */ jsx19(I, { d: P.diamond, ...p });
|
|
1236
|
+
var IconCircle = (p) => /* @__PURE__ */ jsx19(I, { d: P.circle, ...p });
|
|
1052
1237
|
export {
|
|
1053
1238
|
AddressDisplay,
|
|
1054
1239
|
AlertBanner,
|
|
1240
|
+
AppLogo,
|
|
1055
1241
|
Button,
|
|
1056
1242
|
ChainInput,
|
|
1057
1243
|
ConfirmDialog,
|
|
1058
1244
|
CustomSelect,
|
|
1245
|
+
DashboardLayout,
|
|
1059
1246
|
DataTable,
|
|
1060
1247
|
EmptyState,
|
|
1061
1248
|
Field,
|
|
@@ -1089,6 +1276,7 @@ export {
|
|
|
1089
1276
|
SearchInput,
|
|
1090
1277
|
Section,
|
|
1091
1278
|
Select,
|
|
1279
|
+
SidebarNav,
|
|
1092
1280
|
StatusBadge,
|
|
1093
1281
|
Textarea,
|
|
1094
1282
|
tagColor
|
package/package.json
CHANGED
package/src/styles/tokens.css
CHANGED
|
@@ -76,6 +76,17 @@ body {
|
|
|
76
76
|
::-webkit-scrollbar-thumb { background: #1a1a1a; border-radius: 10px; }
|
|
77
77
|
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.15); }
|
|
78
78
|
|
|
79
|
-
/* Anton
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
/* Anton for headings in dashboard apps (admin, dev portal).
|
|
80
|
+
Add class="sphere-dashboard" on <body> or root to activate.
|
|
81
|
+
Sphere wallet does NOT use this — it uses Geist everywhere. */
|
|
82
|
+
.sphere-dashboard h1,
|
|
83
|
+
.sphere-dashboard h2,
|
|
84
|
+
.sphere-dashboard h3 {
|
|
85
|
+
font-family: var(--font-display);
|
|
86
|
+
font-weight: 400;
|
|
87
|
+
letter-spacing: 0.02em;
|
|
88
|
+
text-transform: uppercase;
|
|
89
|
+
-webkit-font-smoothing: antialiased;
|
|
90
|
+
-moz-osx-font-smoothing: grayscale;
|
|
91
|
+
text-rendering: geometricPrecision;
|
|
92
|
+
}
|