@bhooai/nexus-cli 2.0.7 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +1 -1
  2. package/templates/base/apps/admin/package.json.ejs +3 -3
  3. package/templates/base/apps/admin/postcss.config.js +1 -1
  4. package/templates/base/apps/admin/tailwind.config.js +1 -0
  5. package/templates/base/apps/admin/src/App.tsx +0 -38
  6. package/templates/base/apps/admin/src/alertCenter.tsx +0 -151
  7. package/templates/base/apps/admin/src/api.ts +0 -474
  8. package/templates/base/apps/admin/src/assets/bhooai-nexus-logo.svg +0 -25
  9. package/templates/base/apps/admin/src/components/ThemeCentre.tsx +0 -201
  10. package/templates/base/apps/admin/src/components/shell/AppearancePanel.tsx +0 -37
  11. package/templates/base/apps/admin/src/components/shell/Dashboard.tsx +0 -441
  12. package/templates/base/apps/admin/src/components/shell/Login.tsx +0 -69
  13. package/templates/base/apps/admin/src/components/shell/NotifyPanel.tsx +0 -102
  14. package/templates/base/apps/admin/src/components/shell/RailPanel.tsx +0 -133
  15. package/templates/base/apps/admin/src/components/shell/SettingsDialog.tsx +0 -217
  16. package/templates/base/apps/admin/src/components/ui/ConfirmDialog.tsx +0 -38
  17. package/templates/base/apps/admin/src/components/ui/LintChecks.tsx +0 -54
  18. package/templates/base/apps/admin/src/components/ui/PageHead.tsx +0 -13
  19. package/templates/base/apps/admin/src/components/ui/PageHero.tsx +0 -15
  20. package/templates/base/apps/admin/src/icons.tsx +0 -104
  21. package/templates/base/apps/admin/src/index.css +0 -3539
  22. package/templates/base/apps/admin/src/lib/constants.ts +0 -94
  23. package/templates/base/apps/admin/src/lib/theme.ts +0 -80
  24. package/templates/base/apps/admin/src/lib/types.ts +0 -39
  25. package/templates/base/apps/admin/src/lib/utils.ts +0 -147
  26. package/templates/base/apps/admin/src/pages/Config.tsx +0 -108
  27. package/templates/base/apps/admin/src/pages/Databases.tsx +0 -122
  28. package/templates/base/apps/admin/src/pages/Environment.tsx +0 -69
  29. package/templates/base/apps/admin/src/pages/Logs.tsx +0 -270
  30. package/templates/base/apps/admin/src/pages/Monitoring.tsx +0 -88
  31. package/templates/base/apps/admin/src/pages/Overview.tsx +0 -108
  32. package/templates/base/apps/admin/src/pages/Payments.tsx +0 -68
  33. package/templates/base/apps/admin/src/pages/Plugins.tsx +0 -36
  34. package/templates/base/apps/admin/src/pages/Processes.tsx +0 -67
  35. package/templates/base/apps/admin/src/pages/Schema.tsx +0 -130
  36. package/templates/base/apps/admin/src/pages/Users.tsx +0 -144
  37. package/templates/base/apps/admin/src/pages/ai/AddProviderDialog.tsx +0 -150
  38. package/templates/base/apps/admin/src/pages/ai/AiAgents.tsx +0 -31
  39. package/templates/base/apps/admin/src/pages/ai/AiChatPlayground.tsx +0 -208
  40. package/templates/base/apps/admin/src/pages/ai/AiProviders.tsx +0 -276
  41. package/templates/base/apps/admin/src/pages/ai/AiSettings.tsx +0 -84
  42. package/templates/base/apps/admin/src/pages/ai/ProviderCard.tsx +0 -145
  43. package/templates/base/apps/admin/src/pages/ai/ProviderGroup.tsx +0 -50
  44. package/templates/base/apps/admin/src/pages/ai/ProviderKeyDialog.tsx +0 -66
  45. package/templates/base/apps/admin/src/pages/monitoring/RequestSeriesChart.tsx +0 -70
  46. package/templates/base/apps/admin/src/pages/overview/TrafficChart.tsx +0 -32
  47. package/templates/base/apps/admin/src/pages/payments/OrdersTable.tsx +0 -27
  48. package/templates/base/apps/admin/src/pages/payments/PaymentKeysDialog.tsx +0 -74
  49. package/templates/base/apps/admin/src/pages/payments/TestConsole.tsx +0 -173
  50. package/templates/base/apps/admin/src/pages/payments/TransactionsTable.tsx +0 -26
  51. package/templates/base/apps/admin/src/style.css +0 -6517
@@ -1,201 +0,0 @@
1
- import React from 'react';
2
- import { useState } from 'react';
3
- import type { AdminTheme, UiMode, CustomTheme, ParticleConfig } from '../lib/types.js';
4
- import { SWATCH_CPLAETTE, THEME_PRESETS, DEFAULT_PARTICLES, CUSTOM_THEME_KEY, PARTICLES_KEY, TOGGLE_STYLES } from '../lib/constants.js';
5
- import { randomAccentPalette, randomParticleColors } from '../lib/theme.js';
6
- import { Icon } from '../icons.js';
7
- import { PageHead } from './ui/PageHead.js';
8
- import { PageHero } from './ui/PageHero.js';
9
-
10
- export function ThemeCentre({
11
- theme,
12
- onThemeChange,
13
- uiMode,
14
- onUiModeChange,
15
- custom,
16
- onCustom,
17
- particles,
18
- onParticles,
19
- }: {
20
- theme: AdminTheme;
21
- onThemeChange: (theme: AdminTheme) => void;
22
- uiMode: UiMode;
23
- onUiModeChange: (mode: UiMode) => void;
24
- custom: CustomTheme;
25
- onCustom: (partial: Partial<CustomTheme>) => void;
26
- particles: ParticleConfig;
27
- onParticles: (partial: Partial<ParticleConfig>) => void;
28
- }) {
29
- const [copied, setCopied] = useState(false);
30
- const colors: { key: keyof Omit<CustomTheme, 'active'>; label: string; detail: string }[] = [
31
- { key: 'blue', label: 'Primary blue', detail: 'Buttons, focus rings & links' },
32
- { key: 'violet', label: 'Accent violet', detail: 'Highlights & gradients' },
33
- { key: 'pink', label: 'Accent pink', detail: 'Special surfaces & marks' },
34
- { key: 'bg', label: 'Background', detail: 'Base canvas of the shell' },
35
- { key: 'ink', label: 'Foreground text', detail: 'Headings & body ink' },
36
- { key: 'muted', label: 'Muted text', detail: 'Captions & secondary labels' },
37
- ];
38
- const setColor = (key: keyof Omit<CustomTheme, 'active'>, value: string) => onCustom({ [key]: value });
39
- const setParticleColor = (index: number, value: string) => {
40
- const next = [...particles.colors];
41
- next[index] = value;
42
- onParticles({ colors: next });
43
- };
44
- const addParticleColor = () => {
45
- const next = [...particles.colors, SWATCH_CPLAETTE[particles.colors.length % SWATCH_CPLAETTE.length]];
46
- onParticles({ colors: next });
47
- };
48
- const removeParticleColor = (index: number) => {
49
- if (particles.colors.length <= 1) return;
50
- onParticles({ colors: particles.colors.filter((_, i) => i !== index) });
51
- };
52
- const exportJson = () => {
53
- const payload = JSON.stringify({ version: 1, theme, uiMode, custom, particles }, null, 2);
54
- const write = () => { navigator.clipboard.writeText(payload).then(() => setCopied(true)).catch(() => fallback(payload)); };
55
- const fallback = (text: string) => {
56
- const el = document.createElement('textarea');
57
- el.value = text; document.body.appendChild(el); el.select();
58
- try { document.execCommand('copy'); setCopied(true); } catch { /* ignore */ }
59
- document.body.removeChild(el);
60
- };
61
- write();
62
- window.setTimeout(() => setCopied(false), 1600);
63
- };
64
- const importJson = async () => {
65
- let text = '';
66
- try { text = await navigator.clipboard.readText(); } catch { text = window.prompt('Paste theme JSON to import:') ?? ''; }
67
- if (!text) return;
68
- try {
69
- const parsed = JSON.parse(text) as { theme?: AdminTheme; uiMode?: UiMode; custom?: Partial<CustomTheme>; particles?: Partial<ParticleConfig> };
70
- if (parsed.theme && ['aurora', 'midnight', 'violet'].includes(parsed.theme)) onThemeChange(parsed.theme);
71
- if (parsed.uiMode && ['workspace', 'compact', 'focus'].includes(parsed.uiMode)) onUiModeChange(parsed.uiMode);
72
- if (parsed.custom) onCustom(parsed.custom);
73
- if (parsed.particles) onParticles(parsed.particles);
74
- } catch { /* ignore bad import */ }
75
- };
76
- const resetAll = () => {
77
- onCustom({ ...THEME_PRESETS[theme], active: false });
78
- onParticles({ ...DEFAULT_PARTICLES });
79
- try { localStorage.removeItem(CUSTOM_THEME_KEY); localStorage.removeItem(PARTICLES_KEY); } catch { /* ignore */ }
80
- };
81
- const slider = (label: string, detail: string, value: number, min: number, max: number, step: number, display: string, onChange: (v: number) => void) => (
82
- <label className="surface-row">
83
- <span className="surface-meta"><b>{label}</b><small>{detail}</small></span>
84
- <input type="range" className="surface-range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(Number(e.target.value))} />
85
- <em className="surface-value">{display}</em>
86
- </label>
87
- );
88
- return (
89
- <div className="space-y-6">
90
- <PageHead title="Theme Centre">
91
- <div className="heading-actions">
92
- <button type="button" className="workspace-action" onClick={() => { void importJson(); }}><Icon name="download" size={12} /> Import</button>
93
- <button type="button" className="workspace-action" onClick={exportJson}>{copied ? 'Copied' : <><Icon name="upload" size={12} /> Export</>}</button>
94
- <button type="button" className="workspace-action" onClick={resetAll}><Icon name="refresh" size={12} /> Reset all</button>
95
- </div>
96
- </PageHead>
97
- <PageHero kicker="SURFACE STUDIO" title={<>Make it <em>yours.</em></>} desc="Curated themes, your own palette, particle fields and surface tuning — applied live to this workspace and remembered locally in your browser." glyph="palette" art="palette" />
98
- <section className="glass-card space-y-4">
99
- <div className="flex items-center justify-between">
100
- <div><span className="admin-overline">CURATED THEMES</span><h3 className="glass-h3">Start from a surface</h3></div>
101
- <span className="live-badge"><i className="status-dot good" /> LIVE</span>
102
- </div>
103
- <div className="theme-gallery">
104
- {([['aurora', 'Aurora', 'Electric blue glow'], ['midnight', 'Midnight', 'Deep navy calm'], ['violet', 'Violet', 'Indigo shimmer']] as const).map(([id, label, detail]) => {
105
- const preset = THEME_PRESETS[id];
106
- const isActive = !custom.active && theme === id;
107
- return (
108
- <button key={id} type="button" className={`theme-card${isActive ? ' is-active' : ''}`} onClick={() => { onThemeChange(id); onCustom({ ...preset, active: false }); }}>
109
- <span className={`theme-preview ${id}`} />
110
- <span className="theme-card-body"><b>{label}</b><small>{detail}</small></span>
111
- {isActive && <i className="theme-card-check">✓</i>}
112
- </button>
113
- );
114
- })}
115
- </div>
116
- <div className="ui-mode-options ui-mode-row">
117
- {([['workspace', 'Workspace', 'Inspector + tools'], ['compact', 'Compact', 'More content'], ['focus', 'Focus', 'Canvas first']] as const).map(([id, label, detail]) => (
118
- <button key={id} onClick={() => onUiModeChange(id)} className={uiMode === id ? 'is-selected' : ''}><span>{label}</span><small>{detail}</small></button>
119
- ))}
120
- </div>
121
- </section>
122
- <section className="glass-card space-y-4">
123
- <div className="flex items-center justify-between">
124
- <div><span className="admin-overline">CUSTOM THEME</span><h3 className="glass-h3">Your own palette</h3></div>
125
- <div className="flex items-center gap-2">
126
- <button type="button" className="glass-chip-btn" onClick={() => { const p = randomAccentPalette(); onCustom({ ...p, active: !custom.active ? true : custom.active }); }}><Icon name="sparkles" size={12} /> Randomize</button>
127
- <button type="button" className={`custom-toggle${custom.active ? ' is-active' : ''}`} onClick={() => onCustom({ active: !custom.active })}>{custom.active ? 'Applied · live' : 'Apply custom'}</button>
128
- <button type="button" className="glass-chip-btn" onClick={() => onCustom({ ...THEME_PRESETS[theme], active: true })}>Seed from {theme}</button>
129
- </div>
130
- </div>
131
- <p className="text-sm text-slate-400">Tune each color below — the workspace re-themes instantly while custom is applied. Stored locally in your browser.</p>
132
- <div className="custom-grid">
133
- {colors.map((c) => (
134
- <label key={c.key} className="color-row">
135
- <span className="color-swatch"><input type="color" value={custom[c.key]} disabled={!custom.active} onChange={(e) => setColor(c.key, e.target.value)} /></span>
136
- <span className="color-meta"><b>{c.label}</b><small>{c.detail}</small></span>
137
- <input className="glass-input color-hex" value={custom[c.key]} disabled={!custom.active} onChange={(e) => { const v = e.target.value.trim(); if (/^#[0-9a-fA-F]{3,8}$/.test(v)) setColor(c.key, v); }} />
138
- </label>
139
- ))}
140
- </div>
141
- <div className="theme-preview-tile" style={custom.active ? { ['--p-blue' as string]: custom.blue, ['--p-violet' as string]: custom.violet, ['--p-pink' as string]: custom.pink, ['--p-bg' as string]: custom.bg } : undefined}>
142
- <div className="theme-preview-glow" />
143
- <div className="theme-preview-card">
144
- <span className="theme-preview-overline">LIVE PREVIEW</span>
145
- <b className="theme-preview-title">Surface preview</b>
146
- <div className="theme-preview-actions"><button className="glass-chip-btn-primary flex-1 justify-center">Primary</button><button className="glass-chip-btn flex-1 justify-center">chip</button></div>
147
- <div className="theme-preview-dots"><i /><i /><i /></div>
148
- </div>
149
- </div>
150
- </section>
151
- <section className="glass-card space-y-4">
152
- <div className="flex items-center justify-between">
153
- <div><span className="admin-overline">SURFACE TUNING</span><h3 className="glass-h3">Glow, glass & shape</h3></div>
154
- <span className="live-badge"><i className="status-dot good" /> LIVE</span>
155
- </div>
156
- {slider('Ambient glow', 'Mesh & aura strength behind the shell', custom.mesh, 0, 1, 0.02, `${Math.round(custom.mesh * 100)}%`, (v) => onCustom({ mesh: v }))}
157
- {slider('Panel glass', 'Frosted blur behind cards & panels', custom.glass, 0, 1, 0.02, `${Math.round(custom.glass * 100)}%`, (v) => onCustom({ glass: v }))}
158
- {slider('Corner radius', 'Roundness of cards, panels & buttons', custom.radius, 0, 24, 1, `${custom.radius}px`, (v) => onCustom({ radius: v }))}
159
- <div>
160
- <span className="admin-overline">TOGGLE STYLE</span>
161
- <div className="toggle-style-row">
162
- {TOGGLE_STYLES.map((t) => (
163
- <button
164
- key={t.id}
165
- type="button"
166
- className={`toggle-style-btn${custom.toggle === t.id ? ' is-selected' : ''}`}
167
- onClick={() => onCustom({ toggle: t.id })}
168
- >
169
- <span className={`ai-toggle tg-${t.id} is-on toggle-style-preview`}><span className="ai-toggle-knob" /></span>
170
- <span className="toggle-style-meta"><b>{t.label}</b><small>{t.hint}</small></span>
171
- {custom.toggle === t.id && <i className="toggle-style-check">✓</i>}
172
- </button>
173
- ))}
174
- </div>
175
- </div>
176
- </section>
177
- <section className="glass-card space-y-4">
178
- <div className="flex items-center justify-between">
179
- <div><span className="admin-overline">PARTICLE FIELD</span><h3 className="glass-h3">Floating background dust</h3></div>
180
- <div className="flex items-center gap-2">
181
- <button type="button" className="glass-chip-btn" onClick={() => onParticles({ colors: randomParticleColors() })}><Icon name="sparkles" size={12} /> Randomize</button>
182
- <button type="button" className={`custom-toggle${particles.amount > 0 ? ' is-active' : ''}`} onClick={() => onParticles({ amount: particles.amount > 0 ? 0 : 14 })}>{particles.amount > 0 ? 'On' : 'Off'}</button>
183
- </div>
184
- </div>
185
- <p className="text-sm text-slate-400">Control how many particles drift behind the workspace, how fast they rise, and build a custom color list for them.</p>
186
- {slider('Particle amount', 'Count of dots in the field', particles.amount, 0, 48, 1, String(particles.amount), (v) => onParticles({ amount: v }))}
187
- {slider('Particle speed', 'Rise speed multiplier', particles.speed, 0.2, 3, 0.05, `${particles.speed.toFixed(2)}×`, (v) => onParticles({ speed: v }))}
188
- <div className="palette-list">
189
- {particles.colors.map((c, i) => (
190
- <div className="palette-chip" key={i}>
191
- <span className="color-swatch"><input type="color" value={c} onChange={(e) => setParticleColor(i, e.target.value)} /></span>
192
- <input className="glass-input color-hex" value={c} onChange={(e) => { const v = e.target.value.trim(); if (/^#[0-9a-fA-F]{3,8}$/.test(v)) setParticleColor(i, v); }} />
193
- <button type="button" className="row-delete" onClick={() => removeParticleColor(i)} aria-label="Remove color" disabled={particles.colors.length <= 1}>×</button>
194
- </div>
195
- ))}
196
- <button type="button" className="add-color" onClick={addParticleColor}>+ Add color</button>
197
- </div>
198
- </section>
199
- </div>
200
- );
201
- }
@@ -1,37 +0,0 @@
1
- import React from 'react';
2
- import type { AdminTheme, UiMode } from '../../lib/types.js';
3
-
4
- export function AppearancePanel({
5
- theme,
6
- uiMode,
7
- onThemeChange,
8
- onUiModeChange,
9
- }: {
10
- theme: AdminTheme;
11
- uiMode: UiMode;
12
- onThemeChange: (theme: AdminTheme) => void;
13
- onUiModeChange: (mode: UiMode) => void;
14
- }) {
15
- return (
16
- <div className="appearance-panel">
17
- <div className="appearance-heading"><span className="admin-overline">APPEARANCE</span><span>LOCAL</span></div>
18
- <strong>Choose your surface</strong>
19
- <div className="appearance-options">
20
- {([['aurora', 'Aurora', 'Electric blue'], ['midnight', 'Midnight', 'Deep navy'], ['violet', 'Violet', 'Indigo glow']] as const).map(([id, label, detail]) => (
21
- <button key={id} onClick={() => onThemeChange(id)} className={theme === id ? 'is-selected' : ''}>
22
- <span className={`theme-preview ${id}`} />
23
- <span><b>{label}</b><small>{detail}</small></span>
24
- {theme === id && <i>✓</i>}
25
- </button>
26
- ))}
27
- </div>
28
- <div className="appearance-divider" />
29
- <span className="admin-overline">INTERFACE MODE</span>
30
- <div className="ui-mode-options">
31
- {([['workspace', 'Workspace', 'Inspector + tools'], ['compact', 'Compact', 'More content'], ['focus', 'Focus', 'Canvas first']] as const).map(([id, label, detail]) => (
32
- <button key={id} onClick={() => onUiModeChange(id)} className={uiMode === id ? 'is-selected' : ''}><span>{label}</span><small>{detail}</small></button>
33
- ))}
34
- </div>
35
- </div>
36
- );
37
- }