@owox/idp-better-auth 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -0
- package/dist/adapters/database.d.ts +29 -0
- package/dist/adapters/database.d.ts.map +1 -0
- package/dist/adapters/database.js +85 -0
- package/dist/auth/auth-config.d.ts +4 -0
- package/dist/auth/auth-config.d.ts.map +1 -0
- package/dist/auth/auth-config.js +72 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/providers/better-auth-provider.d.ts +34 -0
- package/dist/providers/better-auth-provider.d.ts.map +1 -0
- package/dist/providers/better-auth-provider.js +99 -0
- package/dist/services/authentication-service.d.ts +23 -0
- package/dist/services/authentication-service.d.ts.map +1 -0
- package/dist/services/authentication-service.js +199 -0
- package/dist/services/crypto-service.d.ts +18 -0
- package/dist/services/crypto-service.d.ts.map +1 -0
- package/dist/services/crypto-service.js +100 -0
- package/dist/services/database-service.d.ts +14 -0
- package/dist/services/database-service.d.ts.map +1 -0
- package/dist/services/database-service.js +142 -0
- package/dist/services/magic-link-service.d.ts +10 -0
- package/dist/services/magic-link-service.d.ts.map +1 -0
- package/dist/services/magic-link-service.js +42 -0
- package/dist/services/middleware-service.d.ts +15 -0
- package/dist/services/middleware-service.d.ts.map +1 -0
- package/dist/services/middleware-service.js +38 -0
- package/dist/services/page-service.d.ts +23 -0
- package/dist/services/page-service.d.ts.map +1 -0
- package/dist/services/page-service.js +331 -0
- package/dist/services/request-handler-service.d.ts +10 -0
- package/dist/services/request-handler-service.d.ts.map +1 -0
- package/dist/services/request-handler-service.js +50 -0
- package/dist/services/template-service.d.ts +28 -0
- package/dist/services/template-service.d.ts.map +1 -0
- package/dist/services/template-service.js +198 -0
- package/dist/services/token-service.d.ts +15 -0
- package/dist/services/token-service.d.ts.map +1 -0
- package/dist/services/token-service.js +108 -0
- package/dist/services/user-management-service.d.ts +74 -0
- package/dist/services/user-management-service.d.ts.map +1 -0
- package/dist/services/user-management-service.js +396 -0
- package/dist/templates/admin-add-user.html +298 -0
- package/dist/templates/admin-dashboard.html +214 -0
- package/dist/templates/admin-user-details.html +278 -0
- package/dist/templates/password-setup.html +267 -0
- package/dist/templates/password-success.html +197 -0
- package/dist/templates/sign-in.html +201 -0
- package/dist/types/auth-session.d.ts +25 -0
- package/dist/types/auth-session.d.ts.map +1 -0
- package/dist/types/auth-session.js +1 -0
- package/dist/types/database-models.d.ts +54 -0
- package/dist/types/database-models.d.ts.map +1 -0
- package/dist/types/database-models.js +1 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/package.json +69 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Add User - IDP Better Auth</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
tailwind.config = {
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {
|
|
13
|
+
colors: {
|
|
14
|
+
// OWOX Design System Colors
|
|
15
|
+
background: "oklch(1 0 0)",
|
|
16
|
+
foreground: "oklch(0.3346 0.0123 279.25)",
|
|
17
|
+
card: "oklch(1 0 0)",
|
|
18
|
+
'card-foreground': "oklch(0.3346 0.0123 279.25)",
|
|
19
|
+
popover: "oklch(1 0 0)",
|
|
20
|
+
'popover-foreground': "oklch(0.3346 0.0123 279.25)",
|
|
21
|
+
primary: {
|
|
22
|
+
DEFAULT: "oklch(0.6179 0.2295 250.87)",
|
|
23
|
+
hover: "oklch(0.54 0.23 250.87)",
|
|
24
|
+
foreground: "oklch(0.985 0 0)",
|
|
25
|
+
},
|
|
26
|
+
secondary: {
|
|
27
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
28
|
+
foreground: "oklch(0.205 0 0)",
|
|
29
|
+
},
|
|
30
|
+
muted: {
|
|
31
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
32
|
+
foreground: "oklch(0.5148 0.0128 274.72)",
|
|
33
|
+
},
|
|
34
|
+
accent: {
|
|
35
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
36
|
+
foreground: "oklch(0.205 0 0)",
|
|
37
|
+
},
|
|
38
|
+
destructive: {
|
|
39
|
+
DEFAULT: "oklch(0.577 0.245 27.325)",
|
|
40
|
+
foreground: "oklch(0.985 0 0)",
|
|
41
|
+
},
|
|
42
|
+
border: "oklch(0.922 0 0)",
|
|
43
|
+
input: "oklch(0.922 0 0)",
|
|
44
|
+
ring: "oklch(0.708 0 0)",
|
|
45
|
+
success: {
|
|
46
|
+
DEFAULT: "oklch(0.647 0.165 142.495)",
|
|
47
|
+
foreground: "oklch(0.985 0 0)",
|
|
48
|
+
},
|
|
49
|
+
'brand-blue': {
|
|
50
|
+
50: "oklch(0.985 0.03 250.87)",
|
|
51
|
+
100: "oklch(0.955 0.05 250.87)",
|
|
52
|
+
200: "oklch(0.9 0.08 250.87)",
|
|
53
|
+
300: "oklch(0.8 0.14 250.87)",
|
|
54
|
+
400: "oklch(0.7 0.19 250.87)",
|
|
55
|
+
500: "oklch(0.6179 0.2295 250.87)",
|
|
56
|
+
600: "oklch(0.54 0.23 250.87)",
|
|
57
|
+
700: "oklch(0.44 0.2 250.87)",
|
|
58
|
+
800: "oklch(0.36 0.17 250.87)",
|
|
59
|
+
900: "oklch(0.28 0.14 250.87)",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
</head>
|
|
67
|
+
<body class="bg-white min-h-screen">
|
|
68
|
+
<!-- Header -->
|
|
69
|
+
<header class="bg-white shadow-sm border-b border-border">
|
|
70
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
71
|
+
<div class="flex justify-between items-center h-16">
|
|
72
|
+
<div class="flex items-center space-x-4">
|
|
73
|
+
<a href="/auth/dashboard" class="text-muted-foreground hover:text-card-foreground">
|
|
74
|
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
75
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
76
|
+
</svg>
|
|
77
|
+
</a>
|
|
78
|
+
<h1 class="text-xl font-semibold text-foreground">Add New User</h1>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="flex items-center space-x-4">
|
|
81
|
+
<a href="/" class="text-sm text-primary hover:text-primary/80 transition-colors">
|
|
82
|
+
<svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
83
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
|
|
84
|
+
</svg>
|
|
85
|
+
Back to Site
|
|
86
|
+
</a>
|
|
87
|
+
<a href="/auth/sign-out" class="text-sm text-destructive hover:text-destructive/80 transition-colors">Sign Out</a>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</header>
|
|
92
|
+
|
|
93
|
+
<div class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
94
|
+
<!-- Add User Form -->
|
|
95
|
+
<div class="bg-white shadow sm:rounded-lg border border-border">
|
|
96
|
+
<div class="px-4 py-5 sm:p-6">
|
|
97
|
+
<h3 class="text-lg leading-6 font-medium text-foreground mb-4">User Information</h3>
|
|
98
|
+
|
|
99
|
+
<form id="add-user-form" onsubmit="generateMagicLink(event)" class="space-y-6">
|
|
100
|
+
<div>
|
|
101
|
+
<label for="email" class="block text-sm font-medium text-foreground">Email address</label>
|
|
102
|
+
<div class="mt-1">
|
|
103
|
+
<input type="email" id="email" name="email" required
|
|
104
|
+
class="shadow-sm focus:ring-ring focus:border-ring block w-full sm:text-sm border-input rounded-md bg-white"
|
|
105
|
+
placeholder="user@example.com">
|
|
106
|
+
</div>
|
|
107
|
+
<p class="mt-2 text-sm text-muted-foreground">The user will receive a magic link at this email address.</p>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div>
|
|
111
|
+
<label for="role" class="block text-sm font-medium text-foreground">Role</label>
|
|
112
|
+
<div class="mt-1">
|
|
113
|
+
<select id="role" name="role" required
|
|
114
|
+
class="shadow-sm focus:ring-ring focus:border-ring block w-full sm:text-sm border-input rounded-md bg-white">
|
|
115
|
+
<option value="">Select a role</option>
|
|
116
|
+
{{ROLE_OPTIONS}}
|
|
117
|
+
</select>
|
|
118
|
+
</div>
|
|
119
|
+
<p class="mt-2 text-sm text-muted-foreground">Choose the appropriate role for this user.</p>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="pt-4">
|
|
123
|
+
<button type="submit" id="submit-btn"
|
|
124
|
+
class="w-full inline-flex justify-center items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-ring disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
|
|
125
|
+
<svg id="loading-spinner" class="animate-spin -ml-1 mr-3 h-5 w-5 text-primary-foreground hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
126
|
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
127
|
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
128
|
+
</svg>
|
|
129
|
+
<span id="submit-text">Generate Magic Link</span>
|
|
130
|
+
</button>
|
|
131
|
+
</div>
|
|
132
|
+
</form>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<!-- Success Result -->
|
|
137
|
+
<div id="success-result" class="mt-6 bg-success/10 border border-success/20 rounded-lg p-6 hidden">
|
|
138
|
+
<div class="flex items-start">
|
|
139
|
+
<div class="flex-shrink-0">
|
|
140
|
+
<svg class="h-6 w-6 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
141
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
142
|
+
</svg>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="ml-3 flex-1">
|
|
145
|
+
<h3 class="text-lg font-medium text-success mb-2">Magic Link Generated Successfully!</h3>
|
|
146
|
+
<p class="text-sm text-success mb-4">The magic link has been generated for the user. Share this link with them to complete their registration.</p>
|
|
147
|
+
|
|
148
|
+
<div class="bg-white border border-success/20 rounded-md p-3">
|
|
149
|
+
<label class="block text-sm font-medium text-success mb-2">Magic Link:</label>
|
|
150
|
+
<div class="flex items-center space-x-2">
|
|
151
|
+
<input id="generated-link" type="text" readonly
|
|
152
|
+
class="flex-1 min-w-0 px-3 py-2 border border-success/30 rounded-md text-sm bg-white font-mono text-foreground">
|
|
153
|
+
<button onclick="copyLink()"
|
|
154
|
+
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-success-foreground bg-success hover:bg-success/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-ring transition-colors">
|
|
155
|
+
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
156
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
|
|
157
|
+
</svg>
|
|
158
|
+
Copy
|
|
159
|
+
</button>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div class="mt-4 flex justify-between items-center">
|
|
164
|
+
<button onclick="addAnother()"
|
|
165
|
+
class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-success-foreground bg-success hover:bg-success/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-ring transition-colors">
|
|
166
|
+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
167
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
|
168
|
+
</svg>
|
|
169
|
+
Add Another User
|
|
170
|
+
</button>
|
|
171
|
+
<a href="/auth/dashboard"
|
|
172
|
+
class="inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-md text-foreground bg-white hover:bg-muted/30 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-ring transition-colors">
|
|
173
|
+
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
174
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
175
|
+
</svg>
|
|
176
|
+
Back to Dashboard
|
|
177
|
+
</a>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<!-- Error Result -->
|
|
184
|
+
<div id="error-result" class="mt-6 bg-destructive/10 border border-destructive/20 rounded-lg p-6 hidden">
|
|
185
|
+
<div class="flex items-start">
|
|
186
|
+
<div class="flex-shrink-0">
|
|
187
|
+
<svg class="h-6 w-6 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
188
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16c-.77.833.192 2.5 1.732 2.5z"></path>
|
|
189
|
+
</svg>
|
|
190
|
+
</div>
|
|
191
|
+
<div class="ml-3">
|
|
192
|
+
<h3 class="text-sm font-medium text-destructive-foreground">Error generating magic link</h3>
|
|
193
|
+
<p id="error-message" class="mt-1 text-sm text-red-700"></p>
|
|
194
|
+
<div class="mt-4">
|
|
195
|
+
<button onclick="hideError()"
|
|
196
|
+
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200">
|
|
197
|
+
Try Again
|
|
198
|
+
</button>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<script>
|
|
206
|
+
async function generateMagicLink(event) {
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
|
|
209
|
+
const submitBtn = document.getElementById('submit-btn');
|
|
210
|
+
const spinner = document.getElementById('loading-spinner');
|
|
211
|
+
const submitText = document.getElementById('submit-text');
|
|
212
|
+
const form = document.getElementById('add-user-form');
|
|
213
|
+
|
|
214
|
+
const email = document.getElementById('email').value;
|
|
215
|
+
const role = document.getElementById('role').value;
|
|
216
|
+
|
|
217
|
+
// Show loading state
|
|
218
|
+
submitBtn.disabled = true;
|
|
219
|
+
spinner.classList.remove('hidden');
|
|
220
|
+
submitText.textContent = 'Generating...';
|
|
221
|
+
hideResults();
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const response = await fetch('/auth/add-user', {
|
|
225
|
+
method: 'POST',
|
|
226
|
+
headers: {
|
|
227
|
+
'Content-Type': 'application/json',
|
|
228
|
+
},
|
|
229
|
+
credentials: 'include',
|
|
230
|
+
body: JSON.stringify({ email, role })
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const result = await response.json();
|
|
234
|
+
|
|
235
|
+
if (response.ok) {
|
|
236
|
+
showSuccess(result.magicLink);
|
|
237
|
+
} else {
|
|
238
|
+
showError(result.error || 'Failed to generate magic link');
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
showError('Network error: ' + error.message);
|
|
242
|
+
} finally {
|
|
243
|
+
// Reset loading state
|
|
244
|
+
submitBtn.disabled = false;
|
|
245
|
+
spinner.classList.add('hidden');
|
|
246
|
+
submitText.textContent = 'Generate Magic Link';
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function showSuccess(magicLink) {
|
|
251
|
+
document.getElementById('generated-link').value = magicLink;
|
|
252
|
+
document.getElementById('success-result').classList.remove('hidden');
|
|
253
|
+
document.getElementById('error-result').classList.add('hidden');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function showError(message) {
|
|
257
|
+
document.getElementById('error-message').textContent = message;
|
|
258
|
+
document.getElementById('error-result').classList.remove('hidden');
|
|
259
|
+
document.getElementById('success-result').classList.add('hidden');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function hideResults() {
|
|
263
|
+
document.getElementById('success-result').classList.add('hidden');
|
|
264
|
+
document.getElementById('error-result').classList.add('hidden');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function hideError() {
|
|
268
|
+
document.getElementById('error-result').classList.add('hidden');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function copyLink() {
|
|
272
|
+
const input = document.getElementById('generated-link');
|
|
273
|
+
input.select();
|
|
274
|
+
document.execCommand('copy');
|
|
275
|
+
|
|
276
|
+
// Show feedback
|
|
277
|
+
const button = event.target.closest('button');
|
|
278
|
+
const originalHTML = button.innerHTML;
|
|
279
|
+
button.innerHTML = `<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
280
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
281
|
+
</svg>Copied!`;
|
|
282
|
+
|
|
283
|
+
setTimeout(() => {
|
|
284
|
+
button.innerHTML = originalHTML;
|
|
285
|
+
}, 2000);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function addAnother() {
|
|
289
|
+
// Reset form
|
|
290
|
+
document.getElementById('add-user-form').reset();
|
|
291
|
+
hideResults();
|
|
292
|
+
|
|
293
|
+
// Focus on email input
|
|
294
|
+
document.getElementById('email').focus();
|
|
295
|
+
}
|
|
296
|
+
</script>
|
|
297
|
+
</body>
|
|
298
|
+
</html>
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Admin Dashboard - IDP Better Auth</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
tailwind.config = {
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {
|
|
13
|
+
colors: {
|
|
14
|
+
// OWOX Design System Colors
|
|
15
|
+
background: "oklch(1 0 0)",
|
|
16
|
+
foreground: "oklch(0.3346 0.0123 279.25)",
|
|
17
|
+
card: "oklch(1 0 0)",
|
|
18
|
+
'card-foreground': "oklch(0.3346 0.0123 279.25)",
|
|
19
|
+
popover: "oklch(1 0 0)",
|
|
20
|
+
'popover-foreground': "oklch(0.3346 0.0123 279.25)",
|
|
21
|
+
primary: {
|
|
22
|
+
DEFAULT: "oklch(0.6179 0.2295 250.87)",
|
|
23
|
+
hover: "oklch(0.54 0.23 250.87)",
|
|
24
|
+
foreground: "oklch(0.985 0 0)",
|
|
25
|
+
},
|
|
26
|
+
secondary: {
|
|
27
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
28
|
+
foreground: "oklch(0.205 0 0)",
|
|
29
|
+
},
|
|
30
|
+
muted: {
|
|
31
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
32
|
+
foreground: "oklch(0.5148 0.0128 274.72)",
|
|
33
|
+
},
|
|
34
|
+
accent: {
|
|
35
|
+
DEFAULT: "oklch(0.97 0 0)",
|
|
36
|
+
foreground: "oklch(0.205 0 0)",
|
|
37
|
+
},
|
|
38
|
+
destructive: {
|
|
39
|
+
DEFAULT: "oklch(0.577 0.245 27.325)",
|
|
40
|
+
foreground: "oklch(0.985 0 0)",
|
|
41
|
+
},
|
|
42
|
+
border: "oklch(0.922 0 0)",
|
|
43
|
+
input: "oklch(0.922 0 0)",
|
|
44
|
+
ring: "oklch(0.708 0 0)",
|
|
45
|
+
success: {
|
|
46
|
+
DEFAULT: "oklch(0.647 0.165 142.495)",
|
|
47
|
+
foreground: "oklch(0.985 0 0)",
|
|
48
|
+
},
|
|
49
|
+
'brand-blue': {
|
|
50
|
+
50: "oklch(0.985 0.03 250.87)",
|
|
51
|
+
100: "oklch(0.955 0.05 250.87)",
|
|
52
|
+
200: "oklch(0.9 0.08 250.87)",
|
|
53
|
+
300: "oklch(0.8 0.14 250.87)",
|
|
54
|
+
400: "oklch(0.7 0.19 250.87)",
|
|
55
|
+
500: "oklch(0.6179 0.2295 250.87)",
|
|
56
|
+
600: "oklch(0.54 0.23 250.87)",
|
|
57
|
+
700: "oklch(0.44 0.2 250.87)",
|
|
58
|
+
800: "oklch(0.36 0.17 250.87)",
|
|
59
|
+
900: "oklch(0.28 0.14 250.87)",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<style>
|
|
68
|
+
.table-row:hover {
|
|
69
|
+
background-color: oklch(0.985 0.03 250.87);
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
72
|
+
</head>
|
|
73
|
+
<body class="bg-white min-h-screen">
|
|
74
|
+
<!-- Header -->
|
|
75
|
+
<header class="bg-white shadow-sm border-b border-border">
|
|
76
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
77
|
+
<div class="flex justify-between items-center h-16">
|
|
78
|
+
<h1 class="text-xl font-semibold text-foreground">IDP Admin Dashboard</h1>
|
|
79
|
+
<div class="flex items-center space-x-4">
|
|
80
|
+
<span class="text-sm text-muted-foreground">Welcome, {{CURRENT_USER_EMAIL}}</span>
|
|
81
|
+
<a href="/" class="text-sm text-primary hover:text-primary/80 transition-colors">
|
|
82
|
+
<svg class="inline w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
83
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
|
|
84
|
+
</svg>
|
|
85
|
+
Back to Site
|
|
86
|
+
</a>
|
|
87
|
+
<a href="/auth/sign-out" class="text-sm text-destructive hover:text-destructive/80 transition-colors">Sign Out</a>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</header>
|
|
92
|
+
|
|
93
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
94
|
+
<!-- Page Header -->
|
|
95
|
+
<div class="md:flex md:items-center md:justify-between mb-8">
|
|
96
|
+
<div class="min-w-0 flex-1">
|
|
97
|
+
<h2 class="text-2xl font-bold leading-7 text-foreground sm:truncate">Users Management</h2>
|
|
98
|
+
<p class="mt-1 text-sm text-muted-foreground">Manage all users in your organization</p>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="mt-4 flex md:mt-0 md:ml-4">
|
|
101
|
+
<a href="/auth/add-user" class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-primary-foreground bg-primary hover:bg-primary/90 transition-colors">
|
|
102
|
+
<svg class="-ml-1 mr-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
103
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
|
104
|
+
</svg>
|
|
105
|
+
Add User
|
|
106
|
+
</a>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<!-- Stats Cards -->
|
|
111
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
|
112
|
+
<div class="bg-white overflow-hidden shadow rounded-lg border border-border">
|
|
113
|
+
<div class="p-5">
|
|
114
|
+
<div class="flex items-center">
|
|
115
|
+
<div class="flex-shrink-0">
|
|
116
|
+
<div class="w-8 h-8 bg-muted rounded-full flex items-center justify-center">
|
|
117
|
+
<svg class="w-5 h-5 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
118
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
|
|
119
|
+
</svg>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="ml-5 w-0 flex-1">
|
|
123
|
+
<dl>
|
|
124
|
+
<dt class="text-sm font-medium text-muted-foreground truncate">Total Users</dt>
|
|
125
|
+
<dd class="text-lg font-medium text-foreground">{{TOTAL_USERS}}</dd>
|
|
126
|
+
</dl>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="bg-white overflow-hidden shadow rounded-lg border border-border">
|
|
133
|
+
<div class="p-5">
|
|
134
|
+
<div class="flex items-center">
|
|
135
|
+
<div class="flex-shrink-0">
|
|
136
|
+
<div class="w-8 h-8 bg-muted rounded-full flex items-center justify-center">
|
|
137
|
+
<svg class="w-5 h-5 text-success" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
138
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
139
|
+
</svg>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
<div class="ml-5 w-0 flex-1">
|
|
143
|
+
<dl>
|
|
144
|
+
<dt class="text-sm font-medium text-muted-foreground truncate">Active Users</dt>
|
|
145
|
+
<dd class="text-lg font-medium text-foreground">{{ACTIVE_USERS}}</dd>
|
|
146
|
+
</dl>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<div class="bg-white overflow-hidden shadow rounded-lg border border-border">
|
|
153
|
+
<div class="p-5">
|
|
154
|
+
<div class="flex items-center">
|
|
155
|
+
<div class="flex-shrink-0">
|
|
156
|
+
<div class="w-8 h-8 bg-muted rounded-full flex items-center justify-center">
|
|
157
|
+
<svg class="w-5 h-5 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
158
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
159
|
+
</svg>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="ml-5 w-0 flex-1">
|
|
163
|
+
<dl>
|
|
164
|
+
<dt class="text-sm font-medium text-muted-foreground truncate">Admins</dt>
|
|
165
|
+
<dd class="text-lg font-medium text-foreground">{{ADMIN_USERS}}</dd>
|
|
166
|
+
</dl>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<!-- Users Table -->
|
|
174
|
+
<div class="bg-white shadow overflow-hidden sm:rounded-md border border-border">
|
|
175
|
+
<div class="px-4 py-5 sm:px-6">
|
|
176
|
+
<h3 class="text-lg leading-6 font-medium text-foreground">Users List</h3>
|
|
177
|
+
<p class="mt-1 max-w-2xl text-sm text-muted-foreground">All users in your organization</p>
|
|
178
|
+
</div>
|
|
179
|
+
<div class="overflow-x-auto">
|
|
180
|
+
<table class="min-w-full divide-y divide-border">
|
|
181
|
+
<thead class="bg-muted/30">
|
|
182
|
+
<tr>
|
|
183
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">User</th>
|
|
184
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Role</th>
|
|
185
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Created</th>
|
|
186
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">Updated</th>
|
|
187
|
+
<th class="relative px-6 py-3"><span class="sr-only">Actions</span></th>
|
|
188
|
+
</tr>
|
|
189
|
+
</thead>
|
|
190
|
+
<tbody class="bg-white divide-y divide-border">
|
|
191
|
+
{{USERS_ROWS}}
|
|
192
|
+
</tbody>
|
|
193
|
+
</table>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<!-- Empty State (hidden by default) -->
|
|
198
|
+
<div id="empty-state" class="bg-card shadow overflow-hidden sm:rounded-md hidden">
|
|
199
|
+
<div class="text-center py-12">
|
|
200
|
+
<svg class="mx-auto h-12 w-12 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
201
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
|
|
202
|
+
</svg>
|
|
203
|
+
<h3 class="mt-2 text-sm font-medium text-foreground">No users</h3>
|
|
204
|
+
<p class="mt-1 text-sm text-muted-foreground">Get started by adding your first user.</p>
|
|
205
|
+
<div class="mt-6">
|
|
206
|
+
<a href="/auth/add-user" class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-primary-foreground bg-primary hover:bg-primary/90 transition-colors">
|
|
207
|
+
Add User
|
|
208
|
+
</a>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</body>
|
|
214
|
+
</html>
|