@etherealui/react 0.0.0-stage → 0.0.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/LICENSE +21 -0
- package/README.md +62 -2
- package/dist/index.d.mts +583 -0
- package/dist/index.d.ts +583 -0
- package/dist/index.js +5189 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5189 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +83 -3
- package/src/blocks/app-shell.tsx +441 -0
- package/src/blocks/billing-card.tsx +2 -0
- package/src/blocks/data-table.tsx +479 -0
- package/src/blocks/filter-bar.tsx +134 -0
- package/src/blocks/header-navbar.tsx +7 -0
- package/src/blocks/metric-grid.tsx +5 -0
- package/src/blocks/profile-form.tsx +2 -0
- package/src/blocks/security-settings.tsx +2 -0
- package/src/blocks/settings-blocks.tsx +406 -0
- package/src/blocks/sidebar.tsx +6 -0
- package/src/blocks/stat-card.tsx +7 -0
- package/src/blocks/stat-cards.tsx +212 -0
- package/src/blocks/team-members.tsx +5 -0
- package/src/index.ts +114 -0
- package/src/primitives/accordion.tsx +61 -0
- package/src/primitives/announcement.tsx +33 -0
- package/src/primitives/avatar.tsx +156 -0
- package/src/primitives/badge.tsx +108 -0
- package/src/primitives/breadcrumb.tsx +45 -0
- package/src/primitives/button-group.tsx +79 -0
- package/src/primitives/button.tsx +165 -0
- package/src/primitives/carousel.tsx +84 -0
- package/src/primitives/chart.tsx +831 -0
- package/src/primitives/checkbox.tsx +26 -0
- package/src/primitives/chip.tsx +37 -0
- package/src/primitives/close-button.tsx +29 -0
- package/src/primitives/color-picker.tsx +62 -0
- package/src/primitives/combobox.tsx +123 -0
- package/src/primitives/command-palette.tsx +216 -0
- package/src/primitives/context-menu.tsx +84 -0
- package/src/primitives/date-calendar.tsx +76 -0
- package/src/primitives/date-picker.tsx +400 -0
- package/src/primitives/dialog.tsx +279 -0
- package/src/primitives/divider.tsx +31 -0
- package/src/primitives/drawer.tsx +95 -0
- package/src/primitives/dropdown-menu.tsx +164 -0
- package/src/primitives/file-upload.tsx +123 -0
- package/src/primitives/icon-button.tsx +23 -0
- package/src/primitives/input.tsx +124 -0
- package/src/primitives/modal.tsx +26 -0
- package/src/primitives/pagination.tsx +58 -0
- package/src/primitives/popover.tsx +28 -0
- package/src/primitives/progress.tsx +145 -0
- package/src/primitives/radio-group.tsx +63 -0
- package/src/primitives/select.tsx +207 -0
- package/src/primitives/skeleton.tsx +61 -0
- package/src/primitives/slider.tsx +44 -0
- package/src/primitives/switch.tsx +146 -0
- package/src/primitives/table.tsx +47 -0
- package/src/primitives/tabs.tsx +86 -0
- package/src/primitives/textarea.tsx +40 -0
- package/src/primitives/toast.tsx +71 -0
- package/src/primitives/tooltip.tsx +58 -0
- package/src/styles/globals.css +49 -0
- package/src/templates/control-tower.tsx +41 -0
- package/src/templates/executive-analytics.tsx +272 -0
- package/src/templates/workspace-settings.tsx +179 -0
- package/src/utils/cn.ts +7 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { KeyRound, Copy, Check, Plus, Eye, EyeOff } from "lucide-react"
|
|
3
|
+
import { cn } from "../utils/cn"
|
|
4
|
+
import {
|
|
5
|
+
SidebarShell,
|
|
6
|
+
HeaderNavbar,
|
|
7
|
+
PageHeaderBar,
|
|
8
|
+
} from "../blocks/app-shell"
|
|
9
|
+
import {
|
|
10
|
+
UserProfileFormBlock,
|
|
11
|
+
SecurityPasswordFormBlock,
|
|
12
|
+
TeamRbacTableBlock,
|
|
13
|
+
BillingPlanCardBlock,
|
|
14
|
+
} from "../blocks/settings-blocks"
|
|
15
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "../primitives/tabs"
|
|
16
|
+
import { Badge } from "../primitives/badge"
|
|
17
|
+
import { Button } from "../primitives/button"
|
|
18
|
+
|
|
19
|
+
export const WorkspaceSettingsTemplate: React.FC<{ className?: string }> = ({
|
|
20
|
+
className,
|
|
21
|
+
}) => {
|
|
22
|
+
const [copiedKey, setCopiedKey] = React.useState<string | null>(null)
|
|
23
|
+
const [revealSecret, setRevealSecret] = React.useState(false)
|
|
24
|
+
|
|
25
|
+
const apiKeys = [
|
|
26
|
+
{
|
|
27
|
+
id: "key-prod",
|
|
28
|
+
name: "Production API Key",
|
|
29
|
+
token: revealSecret
|
|
30
|
+
? "sk_live_99482a7f10c3e81140b29d"
|
|
31
|
+
: "sk_live_••••••••••••••••••••9d",
|
|
32
|
+
scope: "Read & Write",
|
|
33
|
+
lastUsed: "2 minutes ago",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "key-ci",
|
|
37
|
+
name: "CI/CD Deployment Token",
|
|
38
|
+
token: "sk_ci_••••••••••••••••••••4a",
|
|
39
|
+
scope: "Read-only",
|
|
40
|
+
lastUsed: "3 hours ago",
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div
|
|
46
|
+
className={cn(
|
|
47
|
+
"flex min-h-[720px] w-full overflow-hidden rounded-2xl border border-zinc-200 bg-zinc-50/40 text-zinc-900 shadow-sm dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-100",
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
>
|
|
51
|
+
<SidebarShell activeId="settings" />
|
|
52
|
+
|
|
53
|
+
<div className="flex flex-1 flex-col min-w-0">
|
|
54
|
+
<HeaderNavbar
|
|
55
|
+
breadcrumbs={["Workspace", "Settings", "General"]}
|
|
56
|
+
/>
|
|
57
|
+
|
|
58
|
+
<main className="flex-1 space-y-6 overflow-y-auto p-6">
|
|
59
|
+
<PageHeaderBar
|
|
60
|
+
title="Workspace Settings"
|
|
61
|
+
subtitle="Manage your profile, team members, billing plan, and API keys."
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<Tabs defaultValue="general" className="w-full">
|
|
65
|
+
<TabsList variant="underline">
|
|
66
|
+
<TabsTrigger variant="underline" value="general">
|
|
67
|
+
Profile
|
|
68
|
+
</TabsTrigger>
|
|
69
|
+
<TabsTrigger variant="underline" value="team">
|
|
70
|
+
Team
|
|
71
|
+
</TabsTrigger>
|
|
72
|
+
<TabsTrigger variant="underline" value="billing">
|
|
73
|
+
Billing
|
|
74
|
+
</TabsTrigger>
|
|
75
|
+
<TabsTrigger variant="underline" value="apikeys">
|
|
76
|
+
API Keys
|
|
77
|
+
</TabsTrigger>
|
|
78
|
+
<TabsTrigger variant="underline" value="security">
|
|
79
|
+
Security
|
|
80
|
+
</TabsTrigger>
|
|
81
|
+
</TabsList>
|
|
82
|
+
|
|
83
|
+
<TabsContent value="general" className="pt-4">
|
|
84
|
+
<UserProfileFormBlock />
|
|
85
|
+
</TabsContent>
|
|
86
|
+
|
|
87
|
+
<TabsContent value="team" className="pt-4">
|
|
88
|
+
<TeamRbacTableBlock />
|
|
89
|
+
</TabsContent>
|
|
90
|
+
|
|
91
|
+
<TabsContent value="billing" className="pt-4">
|
|
92
|
+
<BillingPlanCardBlock />
|
|
93
|
+
</TabsContent>
|
|
94
|
+
|
|
95
|
+
<TabsContent value="apikeys" className="pt-4">
|
|
96
|
+
<div className="rounded-xl border border-zinc-200 bg-white p-6 space-y-5 dark:border-zinc-800 dark:bg-zinc-900">
|
|
97
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between border-b border-zinc-200 pb-4 dark:border-zinc-800">
|
|
98
|
+
<div>
|
|
99
|
+
<h3 className="text-sm font-semibold text-zinc-900 dark:text-zinc-100 flex items-center gap-2">
|
|
100
|
+
<KeyRound className="h-4 w-4 text-blue-600 dark:text-blue-400" />
|
|
101
|
+
API Keys
|
|
102
|
+
</h3>
|
|
103
|
+
<p className="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
|
104
|
+
Use these keys to authenticate API requests from your backend.
|
|
105
|
+
</p>
|
|
106
|
+
</div>
|
|
107
|
+
<div className="flex items-center gap-2">
|
|
108
|
+
<Button
|
|
109
|
+
variant="outline"
|
|
110
|
+
size="sm"
|
|
111
|
+
onClick={() => setRevealSecret(!revealSecret)}
|
|
112
|
+
>
|
|
113
|
+
{revealSecret ? (
|
|
114
|
+
<EyeOff className="h-3.5 w-3.5" />
|
|
115
|
+
) : (
|
|
116
|
+
<Eye className="h-3.5 w-3.5" />
|
|
117
|
+
)}
|
|
118
|
+
{revealSecret ? "Hide" : "Reveal"}
|
|
119
|
+
</Button>
|
|
120
|
+
<Button variant="primary" size="sm">
|
|
121
|
+
<Plus className="h-3.5 w-3.5" />
|
|
122
|
+
Create key
|
|
123
|
+
</Button>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<div className="divide-y divide-zinc-200 rounded-xl border border-zinc-200 dark:divide-zinc-800 dark:border-zinc-800">
|
|
128
|
+
{apiKeys.map((k) => (
|
|
129
|
+
<div
|
|
130
|
+
key={k.id}
|
|
131
|
+
className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between p-4"
|
|
132
|
+
>
|
|
133
|
+
<div className="space-y-1">
|
|
134
|
+
<div className="flex items-center gap-2">
|
|
135
|
+
<span className="text-xs font-medium text-zinc-900 dark:text-zinc-100">
|
|
136
|
+
{k.name}
|
|
137
|
+
</span>
|
|
138
|
+
<Badge variant="default">{k.scope}</Badge>
|
|
139
|
+
</div>
|
|
140
|
+
<p className="font-mono text-xs text-zinc-500 dark:text-zinc-400">
|
|
141
|
+
{k.token}
|
|
142
|
+
</p>
|
|
143
|
+
</div>
|
|
144
|
+
<div className="flex items-center gap-3">
|
|
145
|
+
<span className="text-[11px] text-zinc-400">
|
|
146
|
+
Used {k.lastUsed}
|
|
147
|
+
</span>
|
|
148
|
+
<Button
|
|
149
|
+
variant="outline"
|
|
150
|
+
size="sm"
|
|
151
|
+
onClick={() => {
|
|
152
|
+
navigator.clipboard?.writeText(k.token)
|
|
153
|
+
setCopiedKey(k.id)
|
|
154
|
+
setTimeout(() => setCopiedKey(null), 1500)
|
|
155
|
+
}}
|
|
156
|
+
>
|
|
157
|
+
{copiedKey === k.id ? (
|
|
158
|
+
<Check className="h-3.5 w-3.5 text-emerald-500" />
|
|
159
|
+
) : (
|
|
160
|
+
<Copy className="h-3.5 w-3.5" />
|
|
161
|
+
)}
|
|
162
|
+
{copiedKey === k.id ? "Copied" : "Copy"}
|
|
163
|
+
</Button>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
))}
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</TabsContent>
|
|
170
|
+
|
|
171
|
+
<TabsContent value="security" className="pt-4">
|
|
172
|
+
<SecurityPasswordFormBlock />
|
|
173
|
+
</TabsContent>
|
|
174
|
+
</Tabs>
|
|
175
|
+
</main>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
)
|
|
179
|
+
}
|