@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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -2
  3. package/dist/index.d.mts +583 -0
  4. package/dist/index.d.ts +583 -0
  5. package/dist/index.js +5189 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +5189 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +83 -3
  10. package/src/blocks/app-shell.tsx +441 -0
  11. package/src/blocks/billing-card.tsx +2 -0
  12. package/src/blocks/data-table.tsx +479 -0
  13. package/src/blocks/filter-bar.tsx +134 -0
  14. package/src/blocks/header-navbar.tsx +7 -0
  15. package/src/blocks/metric-grid.tsx +5 -0
  16. package/src/blocks/profile-form.tsx +2 -0
  17. package/src/blocks/security-settings.tsx +2 -0
  18. package/src/blocks/settings-blocks.tsx +406 -0
  19. package/src/blocks/sidebar.tsx +6 -0
  20. package/src/blocks/stat-card.tsx +7 -0
  21. package/src/blocks/stat-cards.tsx +212 -0
  22. package/src/blocks/team-members.tsx +5 -0
  23. package/src/index.ts +114 -0
  24. package/src/primitives/accordion.tsx +61 -0
  25. package/src/primitives/announcement.tsx +33 -0
  26. package/src/primitives/avatar.tsx +156 -0
  27. package/src/primitives/badge.tsx +108 -0
  28. package/src/primitives/breadcrumb.tsx +45 -0
  29. package/src/primitives/button-group.tsx +79 -0
  30. package/src/primitives/button.tsx +165 -0
  31. package/src/primitives/carousel.tsx +84 -0
  32. package/src/primitives/chart.tsx +831 -0
  33. package/src/primitives/checkbox.tsx +26 -0
  34. package/src/primitives/chip.tsx +37 -0
  35. package/src/primitives/close-button.tsx +29 -0
  36. package/src/primitives/color-picker.tsx +62 -0
  37. package/src/primitives/combobox.tsx +123 -0
  38. package/src/primitives/command-palette.tsx +216 -0
  39. package/src/primitives/context-menu.tsx +84 -0
  40. package/src/primitives/date-calendar.tsx +76 -0
  41. package/src/primitives/date-picker.tsx +400 -0
  42. package/src/primitives/dialog.tsx +279 -0
  43. package/src/primitives/divider.tsx +31 -0
  44. package/src/primitives/drawer.tsx +95 -0
  45. package/src/primitives/dropdown-menu.tsx +164 -0
  46. package/src/primitives/file-upload.tsx +123 -0
  47. package/src/primitives/icon-button.tsx +23 -0
  48. package/src/primitives/input.tsx +124 -0
  49. package/src/primitives/modal.tsx +26 -0
  50. package/src/primitives/pagination.tsx +58 -0
  51. package/src/primitives/popover.tsx +28 -0
  52. package/src/primitives/progress.tsx +145 -0
  53. package/src/primitives/radio-group.tsx +63 -0
  54. package/src/primitives/select.tsx +207 -0
  55. package/src/primitives/skeleton.tsx +61 -0
  56. package/src/primitives/slider.tsx +44 -0
  57. package/src/primitives/switch.tsx +146 -0
  58. package/src/primitives/table.tsx +47 -0
  59. package/src/primitives/tabs.tsx +86 -0
  60. package/src/primitives/textarea.tsx +40 -0
  61. package/src/primitives/toast.tsx +71 -0
  62. package/src/primitives/tooltip.tsx +58 -0
  63. package/src/styles/globals.css +49 -0
  64. package/src/templates/control-tower.tsx +41 -0
  65. package/src/templates/executive-analytics.tsx +272 -0
  66. package/src/templates/workspace-settings.tsx +179 -0
  67. 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
+ }
@@ -0,0 +1,7 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
7
+