@create-flow/auth-ui 0.0.1 → 0.0.4
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/components/Hello.d.ts +7 -0
- package/dist/components/Login.d.ts +9 -0
- package/dist/components/OAuthButtons.d.ts +11 -0
- package/dist/components/Sidebar.d.ts +31 -0
- package/dist/components/Signup.d.ts +8 -0
- package/dist/components/UserMenu.d.ts +21 -0
- package/dist/components/VerifyEmail.d.ts +10 -0
- package/dist/index.css +1 -7
- package/dist/index.d.ts +6 -1
- package/dist/index.js +891 -3
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +885 -5
- package/dist/index.modern.js.map +1 -1
- package/dist/styles.css +1 -0
- package/dist/utils/authApi.d.ts +13 -0
- package/dist/utils/css-injection.d.ts +2 -0
- package/package.json +35 -15
- package/src/index.css +28 -0
- package/src/styles.module.css +9 -0
package/dist/index.modern.js
CHANGED
|
@@ -1,13 +1,893 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import React__default, { createElement, useState, useRef, useEffect } from 'react';
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
4
5
|
|
|
6
|
+
var helloStyle = {
|
|
7
|
+
margin: '2em',
|
|
8
|
+
padding: '0.5em',
|
|
9
|
+
border: '2px solid #000',
|
|
10
|
+
fontSize: '2em',
|
|
11
|
+
textAlign: 'center'
|
|
12
|
+
};
|
|
5
13
|
var Hello = function Hello(_ref) {
|
|
6
14
|
var text = _ref.text;
|
|
7
15
|
return createElement("div", {
|
|
8
|
-
|
|
16
|
+
style: helloStyle
|
|
9
17
|
}, "Hello, ", text);
|
|
10
18
|
};
|
|
11
19
|
|
|
12
|
-
|
|
20
|
+
var _iteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator")) : "@@iterator";
|
|
21
|
+
var _asyncIteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator")) : "@@asyncIterator";
|
|
22
|
+
function _catch(body, recover) {
|
|
23
|
+
try {
|
|
24
|
+
var result = body();
|
|
25
|
+
} catch (e) {
|
|
26
|
+
return recover(e);
|
|
27
|
+
}
|
|
28
|
+
if (result && result.then) {
|
|
29
|
+
return result.then(void 0, recover);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
function _finallyRethrows(body, finalizer) {
|
|
34
|
+
try {
|
|
35
|
+
var result = body();
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return finalizer(true, e);
|
|
38
|
+
}
|
|
39
|
+
if (result && result.then) {
|
|
40
|
+
return result.then(finalizer.bind(null, false), finalizer.bind(null, true));
|
|
41
|
+
}
|
|
42
|
+
return finalizer(false, result);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function _extends() {
|
|
46
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
47
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
48
|
+
var t = arguments[e];
|
|
49
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
50
|
+
}
|
|
51
|
+
return n;
|
|
52
|
+
}, _extends.apply(null, arguments);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
var _process$env$NEXT_PUB2, _process$env$NEXT_PUB3;
|
|
56
|
+
var getAuthJson = function getAuthJson(path, host, query) {
|
|
57
|
+
try {
|
|
58
|
+
var url = buildAuthUrl(path, host, query);
|
|
59
|
+
return fetchWithCredentials(url, {
|
|
60
|
+
method: 'GET'
|
|
61
|
+
});
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return Promise.reject(e);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var postAuthJson = function postAuthJson(path, body, host) {
|
|
67
|
+
try {
|
|
68
|
+
var url = buildAuthUrl(path, host);
|
|
69
|
+
return fetchWithCredentials(url, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json'
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify(body)
|
|
75
|
+
});
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return Promise.reject(e);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var fetchWithCredentials = function fetchWithCredentials(url, init) {
|
|
81
|
+
if (init === void 0) {
|
|
82
|
+
init = {};
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
return Promise.resolve(fetch(url.toString(), _extends({
|
|
86
|
+
credentials: 'include',
|
|
87
|
+
cache: 'no-store'
|
|
88
|
+
}, init))).then(function (response) {
|
|
89
|
+
function _temp2() {
|
|
90
|
+
return {
|
|
91
|
+
response: response,
|
|
92
|
+
data: data
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
var data = null;
|
|
96
|
+
var _temp = _catch(function () {
|
|
97
|
+
return Promise.resolve(response.json()).then(function (_response$json) {
|
|
98
|
+
data = _response$json;
|
|
99
|
+
});
|
|
100
|
+
}, function () {});
|
|
101
|
+
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
102
|
+
});
|
|
103
|
+
} catch (e) {
|
|
104
|
+
return Promise.reject(e);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var DEFAULT_AUTH_HOST = function (_process$env$NEXT_PUB) {
|
|
108
|
+
var envHost = (_process$env$NEXT_PUB = process.env.NEXT_PUBLIC_AUTH_API_HOST) === null || _process$env$NEXT_PUB === void 0 ? void 0 : _process$env$NEXT_PUB.trim();
|
|
109
|
+
if (envHost && envHost.length > 0) {
|
|
110
|
+
return envHost;
|
|
111
|
+
}
|
|
112
|
+
return 'https://auth.create-flow.ai';
|
|
113
|
+
}();
|
|
114
|
+
var DEFAULT_APP_ID = (_process$env$NEXT_PUB2 = (_process$env$NEXT_PUB3 = process.env.NEXT_PUBLIC_AUTH_APP_ID) === null || _process$env$NEXT_PUB3 === void 0 ? void 0 : _process$env$NEXT_PUB3.trim()) != null ? _process$env$NEXT_PUB2 : '';
|
|
115
|
+
function normalizeHost(host) {
|
|
116
|
+
var value = (host != null ? host : DEFAULT_AUTH_HOST).trim();
|
|
117
|
+
if (!value) {
|
|
118
|
+
throw new Error('Auth host is not configured');
|
|
119
|
+
}
|
|
120
|
+
if (/^https?:\/\//i.test(value)) {
|
|
121
|
+
return value.replace(/\/+$/g, '');
|
|
122
|
+
}
|
|
123
|
+
return ("https://" + value).replace(/\/+$/g, '');
|
|
124
|
+
}
|
|
125
|
+
function buildAuthUrl(path, host, query) {
|
|
126
|
+
var normalizedHost = normalizeHost(host);
|
|
127
|
+
var normalizedPath = path.startsWith('/') ? path : "/" + path;
|
|
128
|
+
var url = new URL(normalizedPath, normalizedHost);
|
|
129
|
+
if (query) {
|
|
130
|
+
for (var _i = 0, _Object$entries = Object.entries(query); _i < _Object$entries.length; _i++) {
|
|
131
|
+
var _Object$entries$_i = _Object$entries[_i],
|
|
132
|
+
key = _Object$entries$_i[0],
|
|
133
|
+
value = _Object$entries$_i[1];
|
|
134
|
+
if (value !== undefined && value !== null) {
|
|
135
|
+
url.searchParams.set(key, value);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return url;
|
|
140
|
+
}
|
|
141
|
+
function getResolvedAppId(appId) {
|
|
142
|
+
return (appId != null ? appId : DEFAULT_APP_ID).trim();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
var DEFAULT_PROVIDERS = ['google', 'github'];
|
|
146
|
+
function GoogleIcon() {
|
|
147
|
+
return createElement("svg", {
|
|
148
|
+
viewBox: "0 0 24 24",
|
|
149
|
+
className: 'h-4 w-4',
|
|
150
|
+
"aria-hidden": 'true'
|
|
151
|
+
}, createElement("path", {
|
|
152
|
+
d: 'M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z',
|
|
153
|
+
fill: '#4285F4'
|
|
154
|
+
}), createElement("path", {
|
|
155
|
+
d: 'M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z',
|
|
156
|
+
fill: '#34A853'
|
|
157
|
+
}), createElement("path", {
|
|
158
|
+
d: 'M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z',
|
|
159
|
+
fill: '#FBBC05'
|
|
160
|
+
}), createElement("path", {
|
|
161
|
+
d: 'M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z',
|
|
162
|
+
fill: '#EA4335'
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
function GitHubIcon() {
|
|
166
|
+
return createElement("svg", {
|
|
167
|
+
role: 'img',
|
|
168
|
+
viewBox: '0 0 24 24',
|
|
169
|
+
className: 'h-4 w-4',
|
|
170
|
+
"aria-hidden": 'true',
|
|
171
|
+
fill: 'currentColor'
|
|
172
|
+
}, createElement("path", {
|
|
173
|
+
d: 'M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.93.58.11.79-.25.79-.56 0-.28-.01-1.02-.02-2-3.2.7-3.87-1.53-3.87-1.53-.53-1.35-1.3-1.71-1.3-1.71-1.06-.73.08-.72.08-.72 1.17.08 1.78 1.2 1.78 1.2 1.04 1.78 2.72 1.27 3.38.97.11-.75.41-1.27.74-1.56-2.56-.29-5.25-1.28-5.25-5.69 0-1.26.45-2.29 1.2-3.09-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.18 1.18.92-.26 1.9-.39 2.88-.39.98 0 1.96.13 2.88.39 2.2-1.49 3.18-1.18 3.18-1.18.63 1.59.23 2.77.11 3.06.75.8 1.2 1.83 1.2 3.09 0 4.42-2.69 5.39-5.26 5.68.42.36.79 1.09.79 2.2 0 1.59-.01 2.87-.01 3.26 0 .31.21.68.8.56C20.71 21.39 24 17.08 24 12c0-6.35-5.15-11.5-11.5-11.5z'
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
function OAuthButtons(_ref) {
|
|
177
|
+
var appId = _ref.appId,
|
|
178
|
+
authHost = _ref.authHost,
|
|
179
|
+
_ref$redirectTo = _ref.redirectTo,
|
|
180
|
+
redirectTo = _ref$redirectTo === void 0 ? '/dashboard' : _ref$redirectTo,
|
|
181
|
+
providers = _ref.providers,
|
|
182
|
+
className = _ref.className;
|
|
183
|
+
var _React$useState = useState(null),
|
|
184
|
+
loadingProvider = _React$useState[0],
|
|
185
|
+
setLoadingProvider = _React$useState[1];
|
|
186
|
+
var resolvedAppId = getResolvedAppId(appId);
|
|
187
|
+
var providerList = providers && providers.length > 0 ? providers : DEFAULT_PROVIDERS;
|
|
188
|
+
if (!resolvedAppId || providerList.length === 0) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
function buildRedirectUrl(provider) {
|
|
192
|
+
var url = buildAuthUrl('api/auth/oauth', authHost, {
|
|
193
|
+
provider: provider,
|
|
194
|
+
appId: resolvedAppId,
|
|
195
|
+
redirectTo: redirectTo
|
|
196
|
+
});
|
|
197
|
+
return url.toString();
|
|
198
|
+
}
|
|
199
|
+
function handleOAuth(provider) {
|
|
200
|
+
setLoadingProvider(provider);
|
|
201
|
+
window.location.assign(buildRedirectUrl(provider));
|
|
202
|
+
}
|
|
203
|
+
return createElement("div", {
|
|
204
|
+
className: className != null ? className : 'space-y-3'
|
|
205
|
+
}, createElement("div", {
|
|
206
|
+
className: 'relative'
|
|
207
|
+
}, createElement("div", {
|
|
208
|
+
className: 'absolute inset-0 flex items-center'
|
|
209
|
+
}, createElement("div", {
|
|
210
|
+
className: 'w-full border-t border-zinc-200 dark:border-zinc-700'
|
|
211
|
+
})), createElement("div", {
|
|
212
|
+
className: 'relative flex justify-center text-xs'
|
|
213
|
+
}, createElement("span", {
|
|
214
|
+
className: 'bg-white dark:bg-zinc-900 px-3 text-zinc-400'
|
|
215
|
+
}, "or continue with"))), createElement("div", {
|
|
216
|
+
className: 'grid gap-2',
|
|
217
|
+
style: {
|
|
218
|
+
gridTemplateColumns: providerList.length > 1 ? 'repeat(2, minmax(0, 1fr))' : '1fr'
|
|
219
|
+
}
|
|
220
|
+
}, providerList.map(function (provider) {
|
|
221
|
+
return createElement("button", {
|
|
222
|
+
key: provider,
|
|
223
|
+
type: 'button',
|
|
224
|
+
onClick: function onClick() {
|
|
225
|
+
return handleOAuth(provider);
|
|
226
|
+
},
|
|
227
|
+
disabled: loadingProvider !== null,
|
|
228
|
+
className: 'flex items-center justify-center gap-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-medium text-zinc-700 dark:text-zinc-300 transition hover:bg-zinc-50 dark:hover:bg-zinc-700 disabled:opacity-50 disabled:cursor-not-allowed'
|
|
229
|
+
}, loadingProvider === provider ? createElement("span", {
|
|
230
|
+
className: 'h-4 w-4 animate-spin rounded-full border-2 border-zinc-300 border-t-zinc-600'
|
|
231
|
+
}) : provider === 'github' ? createElement(GitHubIcon, null) : createElement(GoogleIcon, null), provider === 'github' ? 'GitHub' : 'Google');
|
|
232
|
+
})));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
var defaultRedirect = '/dashboard';
|
|
236
|
+
var getLoginError = function getLoginError(status) {
|
|
237
|
+
switch (status) {
|
|
238
|
+
case 'invalid_data':
|
|
239
|
+
return 'Please provide a valid email and password.';
|
|
240
|
+
case 'failed':
|
|
241
|
+
default:
|
|
242
|
+
return 'Invalid email or password.';
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
var Login = function Login(_ref) {
|
|
246
|
+
var handleSubmit = function handleSubmit(e) {
|
|
247
|
+
try {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
setError('');
|
|
250
|
+
setIsLoading(true);
|
|
251
|
+
var resolvedAppId = getResolvedAppId(appId);
|
|
252
|
+
if (!resolvedAppId) {
|
|
253
|
+
setError('Missing appId configuration for login.');
|
|
254
|
+
setIsLoading(false);
|
|
255
|
+
return Promise.resolve();
|
|
256
|
+
}
|
|
257
|
+
return Promise.resolve(_finallyRethrows(function () {
|
|
258
|
+
return _catch(function () {
|
|
259
|
+
return Promise.resolve(postAuthJson('api/auth/login', {
|
|
260
|
+
email: email,
|
|
261
|
+
password: password,
|
|
262
|
+
appId: resolvedAppId
|
|
263
|
+
}, authHost)).then(function (_ref2) {
|
|
264
|
+
var response = _ref2.response,
|
|
265
|
+
data = _ref2.data;
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
setError(getLoginError(data === null || data === void 0 ? void 0 : data.status));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (onSuccess) {
|
|
271
|
+
onSuccess();
|
|
272
|
+
} else {
|
|
273
|
+
router.push(redirectTo);
|
|
274
|
+
router.refresh();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}, function (err) {
|
|
278
|
+
console.error(err);
|
|
279
|
+
setError('Something went wrong. Please try again.');
|
|
280
|
+
});
|
|
281
|
+
}, function (_wasThrown, _result) {
|
|
282
|
+
setIsLoading(false);
|
|
283
|
+
if (_wasThrown) throw _result;
|
|
284
|
+
return _result;
|
|
285
|
+
}));
|
|
286
|
+
} catch (e) {
|
|
287
|
+
return Promise.reject(e);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
var appId = _ref.appId,
|
|
291
|
+
authHost = _ref.authHost,
|
|
292
|
+
_ref$redirectTo = _ref.redirectTo,
|
|
293
|
+
redirectTo = _ref$redirectTo === void 0 ? defaultRedirect : _ref$redirectTo,
|
|
294
|
+
onSuccess = _ref.onSuccess;
|
|
295
|
+
var router = useRouter();
|
|
296
|
+
var _useState = useState(''),
|
|
297
|
+
email = _useState[0],
|
|
298
|
+
setEmail = _useState[1];
|
|
299
|
+
var _useState2 = useState(''),
|
|
300
|
+
password = _useState2[0],
|
|
301
|
+
setPassword = _useState2[1];
|
|
302
|
+
var _useState3 = useState(''),
|
|
303
|
+
error = _useState3[0],
|
|
304
|
+
setError = _useState3[1];
|
|
305
|
+
var _useState4 = useState(false),
|
|
306
|
+
isLoading = _useState4[0],
|
|
307
|
+
setIsLoading = _useState4[1];
|
|
308
|
+
return React__default.createElement("div", {
|
|
309
|
+
className: 'w-full max-w-sm'
|
|
310
|
+
}, React__default.createElement("div", {
|
|
311
|
+
className: 'bg-white dark:bg-zinc-900 rounded-2xl shadow-xl border border-zinc-200 dark:border-zinc-800 p-8'
|
|
312
|
+
}, React__default.createElement("div", {
|
|
313
|
+
className: 'mb-8'
|
|
314
|
+
}, React__default.createElement("div", {
|
|
315
|
+
className: 'w-9 h-9 rounded-xl bg-zinc-100 dark:bg-zinc-900 mb-5 flex items-center justify-center'
|
|
316
|
+
}, React__default.createElement("span", {
|
|
317
|
+
className: 'text-zinc-900 dark:text-white font-bold text-sm'
|
|
318
|
+
}, "W")), React__default.createElement("h1", {
|
|
319
|
+
className: 'text-2xl font-semibold text-zinc-900 dark:text-white tracking-tight'
|
|
320
|
+
}, "Welcome back"), React__default.createElement("p", {
|
|
321
|
+
className: 'text-zinc-500 dark:text-zinc-400 text-sm mt-1'
|
|
322
|
+
}, "Sign in to your account")), React__default.createElement("form", {
|
|
323
|
+
onSubmit: handleSubmit,
|
|
324
|
+
className: 'space-y-4'
|
|
325
|
+
}, React__default.createElement("div", null, React__default.createElement("label", {
|
|
326
|
+
className: 'block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5'
|
|
327
|
+
}, "Email"), React__default.createElement("input", {
|
|
328
|
+
type: 'email',
|
|
329
|
+
value: email,
|
|
330
|
+
onChange: function onChange(e) {
|
|
331
|
+
return setEmail(e.target.value);
|
|
332
|
+
},
|
|
333
|
+
placeholder: 'you@example.com',
|
|
334
|
+
required: true,
|
|
335
|
+
autoComplete: 'email',
|
|
336
|
+
className: 'w-full px-3 py-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:border-transparent text-sm transition-colors'
|
|
337
|
+
})), React__default.createElement("div", null, React__default.createElement("label", {
|
|
338
|
+
className: 'block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5'
|
|
339
|
+
}, "Password"), React__default.createElement("input", {
|
|
340
|
+
type: 'password',
|
|
341
|
+
value: password,
|
|
342
|
+
onChange: function onChange(e) {
|
|
343
|
+
return setPassword(e.target.value);
|
|
344
|
+
},
|
|
345
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
346
|
+
required: true,
|
|
347
|
+
autoComplete: 'current-password',
|
|
348
|
+
className: 'w-full px-3 py-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:border-transparent text-sm transition-colors'
|
|
349
|
+
})), error && React__default.createElement("p", {
|
|
350
|
+
className: 'text-sm text-red-500 dark:text-red-400 bg-red-50 dark:bg-red-950/20 px-3 py-2 rounded-lg'
|
|
351
|
+
}, error), React__default.createElement("button", {
|
|
352
|
+
type: 'submit',
|
|
353
|
+
disabled: isLoading,
|
|
354
|
+
className: 'w-full py-2.5 px-4 bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 rounded-lg text-sm font-medium hover:bg-zinc-700 dark:hover:bg-zinc-100 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors'
|
|
355
|
+
}, isLoading ? 'Signing in…' : 'Sign in')), React__default.createElement("div", {
|
|
356
|
+
className: 'mt-4'
|
|
357
|
+
}, React__default.createElement(OAuthButtons, {
|
|
358
|
+
appId: appId,
|
|
359
|
+
authHost: authHost,
|
|
360
|
+
redirectTo: redirectTo
|
|
361
|
+
})), React__default.createElement("p", {
|
|
362
|
+
className: 'mt-6 text-center text-sm text-zinc-500 dark:text-zinc-400'
|
|
363
|
+
}, "Don't have an account?", ' ', React__default.createElement(Link, {
|
|
364
|
+
href: '/signup',
|
|
365
|
+
className: 'font-medium text-zinc-900 dark:text-white hover:underline underline-offset-4'
|
|
366
|
+
}, "Sign up"))));
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
var defaultError = 'Something went wrong. Please try again.';
|
|
370
|
+
var statusMessage = function statusMessage(status) {
|
|
371
|
+
switch (status) {
|
|
372
|
+
case 'invalid_data':
|
|
373
|
+
return 'Please fill out all required fields.';
|
|
374
|
+
case 'user_exists':
|
|
375
|
+
return 'An account with that email already exists.';
|
|
376
|
+
case 'sign_up_disabled':
|
|
377
|
+
return 'Sign ups are disabled for this app.';
|
|
378
|
+
case 'app_not_found':
|
|
379
|
+
return 'We could not find the app configuration.';
|
|
380
|
+
default:
|
|
381
|
+
return defaultError;
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
var Signup = function Signup(_ref) {
|
|
385
|
+
var handleSubmit = function handleSubmit(e) {
|
|
386
|
+
try {
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
setError('');
|
|
389
|
+
setIsLoading(true);
|
|
390
|
+
var resolvedAppId = getResolvedAppId(appId);
|
|
391
|
+
if (!resolvedAppId) {
|
|
392
|
+
setError('Missing appId configuration for sign up.');
|
|
393
|
+
setIsLoading(false);
|
|
394
|
+
return Promise.resolve();
|
|
395
|
+
}
|
|
396
|
+
return Promise.resolve(_finallyRethrows(function () {
|
|
397
|
+
return _catch(function () {
|
|
398
|
+
return Promise.resolve(postAuthJson('api/auth/register', {
|
|
399
|
+
name: name,
|
|
400
|
+
email: email,
|
|
401
|
+
password: password,
|
|
402
|
+
appId: resolvedAppId
|
|
403
|
+
}, authHost)).then(function (_ref2) {
|
|
404
|
+
var response = _ref2.response,
|
|
405
|
+
data = _ref2.data;
|
|
406
|
+
if (!response.ok) {
|
|
407
|
+
setError(statusMessage(data === null || data === void 0 ? void 0 : data.status));
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
setRegistered(true);
|
|
411
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
|
|
412
|
+
});
|
|
413
|
+
}, function (err) {
|
|
414
|
+
console.error(err);
|
|
415
|
+
setError(defaultError);
|
|
416
|
+
});
|
|
417
|
+
}, function (_wasThrown, _result) {
|
|
418
|
+
setIsLoading(false);
|
|
419
|
+
if (_wasThrown) throw _result;
|
|
420
|
+
return _result;
|
|
421
|
+
}));
|
|
422
|
+
} catch (e) {
|
|
423
|
+
return Promise.reject(e);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var appId = _ref.appId,
|
|
427
|
+
authHost = _ref.authHost,
|
|
428
|
+
onSuccess = _ref.onSuccess;
|
|
429
|
+
var _useState = useState(''),
|
|
430
|
+
name = _useState[0],
|
|
431
|
+
setName = _useState[1];
|
|
432
|
+
var _useState2 = useState(''),
|
|
433
|
+
email = _useState2[0],
|
|
434
|
+
setEmail = _useState2[1];
|
|
435
|
+
var _useState3 = useState(''),
|
|
436
|
+
password = _useState3[0],
|
|
437
|
+
setPassword = _useState3[1];
|
|
438
|
+
var _useState4 = useState(''),
|
|
439
|
+
error = _useState4[0],
|
|
440
|
+
setError = _useState4[1];
|
|
441
|
+
var _useState5 = useState(false),
|
|
442
|
+
isLoading = _useState5[0],
|
|
443
|
+
setIsLoading = _useState5[1];
|
|
444
|
+
var _useState6 = useState(false),
|
|
445
|
+
registered = _useState6[0],
|
|
446
|
+
setRegistered = _useState6[1];
|
|
447
|
+
if (registered) {
|
|
448
|
+
return React__default.createElement("div", {
|
|
449
|
+
className: 'w-full max-w-sm'
|
|
450
|
+
}, React__default.createElement("div", {
|
|
451
|
+
className: 'bg-white dark:bg-zinc-900 rounded-2xl shadow-xl border border-zinc-200 dark:border-zinc-800 p-8 text-center'
|
|
452
|
+
}, React__default.createElement("div", {
|
|
453
|
+
className: 'flex justify-center mb-5'
|
|
454
|
+
}, React__default.createElement("div", {
|
|
455
|
+
className: 'w-14 h-14 rounded-2xl bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center text-2xl'
|
|
456
|
+
}, "\u2709\uFE0F")), React__default.createElement("h1", {
|
|
457
|
+
className: 'text-xl font-semibold text-zinc-900 dark:text-white tracking-tight mb-2'
|
|
458
|
+
}, "Check your email"), React__default.createElement("p", {
|
|
459
|
+
className: 'text-zinc-500 dark:text-zinc-400 text-sm leading-relaxed mb-6'
|
|
460
|
+
}, "We sent a verification link to", ' ', React__default.createElement("span", {
|
|
461
|
+
className: 'font-medium text-zinc-700 dark:text-zinc-300'
|
|
462
|
+
}, email), ". Click it to activate your account."), React__default.createElement("p", {
|
|
463
|
+
className: 'text-xs text-zinc-400'
|
|
464
|
+
}, "Already verified?", ' ', React__default.createElement(Link, {
|
|
465
|
+
href: '/login',
|
|
466
|
+
className: 'text-zinc-600 dark:text-zinc-300 underline underline-offset-2 hover:text-zinc-900 dark:hover:text-white'
|
|
467
|
+
}, "Sign in"))));
|
|
468
|
+
}
|
|
469
|
+
return React__default.createElement("div", {
|
|
470
|
+
className: 'w-full max-w-sm'
|
|
471
|
+
}, React__default.createElement("div", {
|
|
472
|
+
className: 'bg-white dark:bg-zinc-900 rounded-2xl shadow-xl border border-zinc-200 dark:border-zinc-800 p-8'
|
|
473
|
+
}, React__default.createElement("div", {
|
|
474
|
+
className: 'mb-8'
|
|
475
|
+
}, React__default.createElement("h1", {
|
|
476
|
+
className: 'text-2xl font-semibold text-zinc-900 dark:text-white tracking-tight'
|
|
477
|
+
}, "Create an account"), React__default.createElement("p", {
|
|
478
|
+
className: 'text-zinc-500 dark:text-zinc-400 text-sm mt-1'
|
|
479
|
+
}, "Get started for free today")), React__default.createElement("form", {
|
|
480
|
+
onSubmit: handleSubmit,
|
|
481
|
+
className: 'space-y-4'
|
|
482
|
+
}, React__default.createElement("div", null, React__default.createElement("label", {
|
|
483
|
+
className: 'block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5'
|
|
484
|
+
}, "Name"), React__default.createElement("input", {
|
|
485
|
+
type: 'text',
|
|
486
|
+
value: name,
|
|
487
|
+
onChange: function onChange(e) {
|
|
488
|
+
return setName(e.target.value);
|
|
489
|
+
},
|
|
490
|
+
placeholder: 'Jane Smith',
|
|
491
|
+
autoComplete: 'name',
|
|
492
|
+
className: 'w-full px-3 py-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:border-transparent text-sm transition-colors'
|
|
493
|
+
})), React__default.createElement("div", null, React__default.createElement("label", {
|
|
494
|
+
className: 'block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5'
|
|
495
|
+
}, "Email"), React__default.createElement("input", {
|
|
496
|
+
type: 'email',
|
|
497
|
+
value: email,
|
|
498
|
+
onChange: function onChange(e) {
|
|
499
|
+
return setEmail(e.target.value);
|
|
500
|
+
},
|
|
501
|
+
placeholder: 'you@example.com',
|
|
502
|
+
required: true,
|
|
503
|
+
autoComplete: 'email',
|
|
504
|
+
className: 'w-full px-3 py-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:border-transparent text-sm transition-colors'
|
|
505
|
+
})), React__default.createElement("div", null, React__default.createElement("label", {
|
|
506
|
+
className: 'block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5'
|
|
507
|
+
}, "Password"), React__default.createElement("input", {
|
|
508
|
+
type: 'password',
|
|
509
|
+
value: password,
|
|
510
|
+
onChange: function onChange(e) {
|
|
511
|
+
return setPassword(e.target.value);
|
|
512
|
+
},
|
|
513
|
+
placeholder: 'Min. 6 characters',
|
|
514
|
+
required: true,
|
|
515
|
+
autoComplete: 'new-password',
|
|
516
|
+
className: 'w-full px-3 py-2 rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-white placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-zinc-900 dark:focus:ring-zinc-300 focus:border-transparent text-sm transition-colors'
|
|
517
|
+
})), error && React__default.createElement("p", {
|
|
518
|
+
className: 'text-sm text-red-500 dark:text-red-400 bg-red-50 dark:bg-red-950/20 px-3 py-2 rounded-lg'
|
|
519
|
+
}, error), React__default.createElement("button", {
|
|
520
|
+
type: 'submit',
|
|
521
|
+
disabled: isLoading,
|
|
522
|
+
className: 'w-full py-2.5 px-4 bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 rounded-lg text-sm font-medium hover:bg-zinc-700 dark:hover:bg-zinc-100 focus:outline-none focus:ring-2 focus:ring-zinc-900 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors'
|
|
523
|
+
}, isLoading ? 'Creating account…' : 'Create account')), React__default.createElement("div", {
|
|
524
|
+
className: 'mt-4'
|
|
525
|
+
}, React__default.createElement(OAuthButtons, {
|
|
526
|
+
appId: appId,
|
|
527
|
+
authHost: authHost
|
|
528
|
+
})), React__default.createElement("p", {
|
|
529
|
+
className: 'mt-6 text-center text-sm text-zinc-500 dark:text-zinc-400'
|
|
530
|
+
}, "Already have an account?", ' ', React__default.createElement(Link, {
|
|
531
|
+
href: '/login',
|
|
532
|
+
className: 'font-medium text-zinc-900 dark:text-white hover:underline underline-offset-4'
|
|
533
|
+
}, "Sign in"))));
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
var VerifyEmail = function VerifyEmail(_ref) {
|
|
537
|
+
var searchParams = _ref.searchParams,
|
|
538
|
+
appId = _ref.appId,
|
|
539
|
+
authHost = _ref.authHost;
|
|
540
|
+
return Promise.resolve(searchParams).then(function (_ref2) {
|
|
541
|
+
var _exit = false;
|
|
542
|
+
var token = _ref2.token;
|
|
543
|
+
function _temp2(_result) {
|
|
544
|
+
return _exit ? _result : React__default.createElement(VerifyResult, {
|
|
545
|
+
status: 'success'
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
if (!token) {
|
|
549
|
+
return React__default.createElement(VerifyResult, {
|
|
550
|
+
status: 'invalid'
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
var resolvedAppId = getResolvedAppId(appId);
|
|
554
|
+
if (!resolvedAppId) {
|
|
555
|
+
return React__default.createElement(VerifyResult, {
|
|
556
|
+
status: 'error',
|
|
557
|
+
message: 'Missing appId configuration for verification.'
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
var _temp = _catch(function () {
|
|
561
|
+
return Promise.resolve(getAuthJson('api/auth/verify-email', authHost, {
|
|
562
|
+
token: token,
|
|
563
|
+
appId: resolvedAppId
|
|
564
|
+
})).then(function (_ref3) {
|
|
565
|
+
var response = _ref3.response,
|
|
566
|
+
data = _ref3.data;
|
|
567
|
+
if (!response.ok) {
|
|
568
|
+
var _ref4, _data$message;
|
|
569
|
+
var message = (_ref4 = (_data$message = data === null || data === void 0 ? void 0 : data.message) != null ? _data$message : data === null || data === void 0 ? void 0 : data.status) != null ? _ref4 : 'Verification failed.';
|
|
570
|
+
var _React$createElement = React__default.createElement(VerifyResult, {
|
|
571
|
+
status: 'error',
|
|
572
|
+
message: message
|
|
573
|
+
});
|
|
574
|
+
_exit = true;
|
|
575
|
+
return _React$createElement;
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
}, function (err) {
|
|
579
|
+
console.error(err);
|
|
580
|
+
var _React$createElement2 = React__default.createElement(VerifyResult, {
|
|
581
|
+
status: 'error',
|
|
582
|
+
message: 'Unable to reach the verification service.'
|
|
583
|
+
});
|
|
584
|
+
_exit = true;
|
|
585
|
+
return _React$createElement2;
|
|
586
|
+
});
|
|
587
|
+
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
588
|
+
});
|
|
589
|
+
};
|
|
590
|
+
function VerifyResult(_ref5) {
|
|
591
|
+
var status = _ref5.status,
|
|
592
|
+
message = _ref5.message;
|
|
593
|
+
var isSuccess = status === 'success';
|
|
594
|
+
return React__default.createElement("div", {
|
|
595
|
+
className: 'fixed inset-0 flex flex-col md:flex-row bg-white dark:bg-zinc-950 overflow-auto'
|
|
596
|
+
}, React__default.createElement("div", {
|
|
597
|
+
className: 'hidden md:flex md:w-5/12 lg:w-[42%] flex-col bg-zinc-900 relative overflow-hidden'
|
|
598
|
+
}, React__default.createElement("div", {
|
|
599
|
+
className: 'absolute -top-32 -left-32 w-96 h-96 rounded-full bg-zinc-800 opacity-60'
|
|
600
|
+
}), React__default.createElement("div", {
|
|
601
|
+
className: 'absolute -bottom-24 -right-24 w-80 h-80 rounded-full bg-zinc-800 opacity-60'
|
|
602
|
+
}), React__default.createElement("div", {
|
|
603
|
+
className: 'absolute inset-0 opacity-[0.03]',
|
|
604
|
+
style: {
|
|
605
|
+
backgroundImage: 'radial-gradient(circle, #ffffff 1px, transparent 1px)',
|
|
606
|
+
backgroundSize: '28px 28px'
|
|
607
|
+
}
|
|
608
|
+
}), React__default.createElement("div", {
|
|
609
|
+
className: 'relative z-10 p-8'
|
|
610
|
+
}, React__default.createElement("div", {
|
|
611
|
+
className: 'flex items-center gap-2.5'
|
|
612
|
+
}, React__default.createElement("div", {
|
|
613
|
+
className: 'w-8 h-8 rounded-lg bg-white flex items-center justify-center'
|
|
614
|
+
}, React__default.createElement("span", {
|
|
615
|
+
className: 'text-zinc-900 font-bold text-sm'
|
|
616
|
+
}, "W")), React__default.createElement("span", {
|
|
617
|
+
className: 'text-white font-semibold tracking-tight'
|
|
618
|
+
}, "YourApp"))), React__default.createElement("div", {
|
|
619
|
+
className: 'relative z-10 flex-1 flex flex-col items-center justify-center px-12 pb-16 text-center'
|
|
620
|
+
}, React__default.createElement("div", {
|
|
621
|
+
className: "mb-8 flex h-24 w-24 items-center justify-center rounded-3xl text-4xl font-bold shadow-2xl " + (isSuccess ? 'bg-emerald-500 text-white' : 'bg-red-500 text-white')
|
|
622
|
+
}, isSuccess ? '✓' : '✕'), React__default.createElement("p", {
|
|
623
|
+
className: 'mb-3 text-xs font-semibold uppercase tracking-widest text-zinc-500'
|
|
624
|
+
}, "Email Verification"), React__default.createElement("h2", {
|
|
625
|
+
className: 'text-2xl font-bold leading-snug text-white max-w-xs'
|
|
626
|
+
}, isSuccess ? "You're all verified and ready to go." : 'Something went wrong with your link.'))), React__default.createElement("div", {
|
|
627
|
+
className: 'flex flex-1 flex-col items-center justify-center px-8 py-12 md:px-16 lg:px-24'
|
|
628
|
+
}, React__default.createElement("div", {
|
|
629
|
+
className: 'mb-10 flex items-center gap-2.5 md:hidden'
|
|
630
|
+
}, React__default.createElement("div", {
|
|
631
|
+
className: 'w-8 h-8 rounded-lg bg-zinc-900 dark:bg-white flex items-center justify-center'
|
|
632
|
+
}, React__default.createElement("span", {
|
|
633
|
+
className: 'text-white dark:text-zinc-900 font-bold text-sm'
|
|
634
|
+
}, "W")), React__default.createElement("span", {
|
|
635
|
+
className: 'font-semibold tracking-tight text-zinc-900 dark:text-white'
|
|
636
|
+
}, "YourApp")), React__default.createElement("div", {
|
|
637
|
+
className: 'w-full max-w-md'
|
|
638
|
+
}, React__default.createElement("div", {
|
|
639
|
+
className: 'mb-7 flex justify-start md:hidden'
|
|
640
|
+
}, React__default.createElement("div", {
|
|
641
|
+
className: "flex h-16 w-16 items-center justify-center rounded-2xl text-3xl font-bold " + (isSuccess ? 'bg-emerald-500 text-white' : 'bg-red-500 text-white')
|
|
642
|
+
}, isSuccess ? '✓' : '✕')), React__default.createElement("p", {
|
|
643
|
+
className: 'mb-3 text-xs font-semibold uppercase tracking-widest text-zinc-400 dark:text-zinc-500 hidden md:block'
|
|
644
|
+
}, "Email Verification"), React__default.createElement("h1", {
|
|
645
|
+
className: 'mb-4 text-4xl font-bold tracking-tight text-zinc-900 dark:text-white leading-tight'
|
|
646
|
+
}, isSuccess ? 'Email verified!' : 'Verification failed'), React__default.createElement("p", {
|
|
647
|
+
className: 'mb-10 text-base leading-relaxed text-zinc-500 dark:text-zinc-400 max-w-sm'
|
|
648
|
+
}, isSuccess ? 'Your email address has been confirmed and your account is active. Sign in to get started.' : message != null ? message : 'This verification link is invalid or has expired. Links are only valid for 24 hours.'), React__default.createElement(Link, {
|
|
649
|
+
href: '/login',
|
|
650
|
+
className: 'block w-full rounded-xl bg-zinc-900 dark:bg-white px-6 py-3.5 text-center text-sm font-semibold text-white dark:text-zinc-900 transition hover:bg-zinc-700 dark:hover:bg-zinc-100'
|
|
651
|
+
}, isSuccess ? 'Sign in to your account →' : 'Back to login'), !isSuccess && React__default.createElement("p", {
|
|
652
|
+
className: 'mt-5 text-sm text-zinc-400 dark:text-zinc-500'
|
|
653
|
+
}, "Need a new link?", ' ', React__default.createElement(Link, {
|
|
654
|
+
href: '/signup',
|
|
655
|
+
className: 'text-zinc-600 dark:text-zinc-300 underline underline-offset-2 hover:text-zinc-900 dark:hover:text-white'
|
|
656
|
+
}, "Sign up again")), isSuccess && React__default.createElement("p", {
|
|
657
|
+
className: 'mt-5 text-sm text-zinc-400 dark:text-zinc-500'
|
|
658
|
+
}, "Check your inbox \u2014 we've sent you a welcome email."))));
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function UserIcon(_ref) {
|
|
662
|
+
var className = _ref.className;
|
|
663
|
+
return React__default.createElement("svg", {
|
|
664
|
+
className: className,
|
|
665
|
+
viewBox: "0 0 24 24",
|
|
666
|
+
fill: "none",
|
|
667
|
+
stroke: "currentColor",
|
|
668
|
+
strokeWidth: "1.75",
|
|
669
|
+
strokeLinecap: "round",
|
|
670
|
+
strokeLinejoin: "round"
|
|
671
|
+
}, React__default.createElement("circle", {
|
|
672
|
+
cx: "12",
|
|
673
|
+
cy: "8",
|
|
674
|
+
r: "4"
|
|
675
|
+
}), React__default.createElement("path", {
|
|
676
|
+
d: "M4 20c0-4 3.6-7 8-7s8 3 8 7"
|
|
677
|
+
}));
|
|
678
|
+
}
|
|
679
|
+
function SettingsIcon(_ref2) {
|
|
680
|
+
var className = _ref2.className;
|
|
681
|
+
return React__default.createElement("svg", {
|
|
682
|
+
className: className,
|
|
683
|
+
viewBox: "0 0 24 24",
|
|
684
|
+
fill: "none",
|
|
685
|
+
stroke: "currentColor",
|
|
686
|
+
strokeWidth: "1.75",
|
|
687
|
+
strokeLinecap: "round",
|
|
688
|
+
strokeLinejoin: "round"
|
|
689
|
+
}, React__default.createElement("circle", {
|
|
690
|
+
cx: "12",
|
|
691
|
+
cy: "12",
|
|
692
|
+
r: "3"
|
|
693
|
+
}), React__default.createElement("path", {
|
|
694
|
+
d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"
|
|
695
|
+
}));
|
|
696
|
+
}
|
|
697
|
+
function LogOutIcon(_ref3) {
|
|
698
|
+
var className = _ref3.className;
|
|
699
|
+
return React__default.createElement("svg", {
|
|
700
|
+
className: className,
|
|
701
|
+
viewBox: "0 0 24 24",
|
|
702
|
+
fill: "none",
|
|
703
|
+
stroke: "currentColor",
|
|
704
|
+
strokeWidth: "1.75",
|
|
705
|
+
strokeLinecap: "round",
|
|
706
|
+
strokeLinejoin: "round"
|
|
707
|
+
}, React__default.createElement("path", {
|
|
708
|
+
d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"
|
|
709
|
+
}), React__default.createElement("polyline", {
|
|
710
|
+
points: "16,17 21,12 16,7"
|
|
711
|
+
}), React__default.createElement("line", {
|
|
712
|
+
x1: "21",
|
|
713
|
+
y1: "12",
|
|
714
|
+
x2: "9",
|
|
715
|
+
y2: "12"
|
|
716
|
+
}));
|
|
717
|
+
}
|
|
718
|
+
function ChevronsUpDownIcon(_ref4) {
|
|
719
|
+
var className = _ref4.className;
|
|
720
|
+
return React__default.createElement("svg", {
|
|
721
|
+
className: className,
|
|
722
|
+
viewBox: "0 0 24 24",
|
|
723
|
+
fill: "none",
|
|
724
|
+
stroke: "currentColor",
|
|
725
|
+
strokeWidth: "2",
|
|
726
|
+
strokeLinecap: "round",
|
|
727
|
+
strokeLinejoin: "round"
|
|
728
|
+
}, React__default.createElement("path", {
|
|
729
|
+
d: "M7 15l5 5 5-5M7 9l5-5 5 5"
|
|
730
|
+
}));
|
|
731
|
+
}
|
|
732
|
+
var AVATAR_COLORS = ["bg-violet-600", "bg-indigo-600", "bg-sky-600", "bg-emerald-600", "bg-amber-600", "bg-rose-600"];
|
|
733
|
+
function getAvatarColor(name) {
|
|
734
|
+
var hash = 0;
|
|
735
|
+
for (var i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
736
|
+
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
737
|
+
}
|
|
738
|
+
function getInitials(name) {
|
|
739
|
+
return name.split(" ").filter(Boolean).map(function (w) {
|
|
740
|
+
return w[0];
|
|
741
|
+
}).join("").toUpperCase().slice(0, 2);
|
|
742
|
+
}
|
|
743
|
+
var UserMenu = function UserMenu(_ref5) {
|
|
744
|
+
var _user$email;
|
|
745
|
+
var handleLogout = function handleLogout() {
|
|
746
|
+
try {
|
|
747
|
+
var _temp3 = function _temp3() {
|
|
748
|
+
if (onLogout) {
|
|
749
|
+
onLogout();
|
|
750
|
+
} else {
|
|
751
|
+
router.push(logoutRedirectTo);
|
|
752
|
+
router.refresh();
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
var resolvedAppId = getResolvedAppId(appId);
|
|
756
|
+
var _temp2 = _catch(function () {
|
|
757
|
+
return Promise.resolve(getAuthJson("api/auth/logout", authHost, resolvedAppId ? {
|
|
758
|
+
appId: resolvedAppId
|
|
759
|
+
} : undefined)).then(function () {});
|
|
760
|
+
}, function (err) {
|
|
761
|
+
console.error("Logout error:", err);
|
|
762
|
+
});
|
|
763
|
+
return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2));
|
|
764
|
+
} catch (e) {
|
|
765
|
+
return Promise.reject(e);
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
var userProp = _ref5.user,
|
|
769
|
+
appId = _ref5.appId,
|
|
770
|
+
authHost = _ref5.authHost,
|
|
771
|
+
_ref5$logoutRedirectT = _ref5.logoutRedirectTo,
|
|
772
|
+
logoutRedirectTo = _ref5$logoutRedirectT === void 0 ? "/" : _ref5$logoutRedirectT,
|
|
773
|
+
_ref5$profileHref = _ref5.profileHref,
|
|
774
|
+
profileHref = _ref5$profileHref === void 0 ? "/profile" : _ref5$profileHref,
|
|
775
|
+
_ref5$settingsHref = _ref5.settingsHref,
|
|
776
|
+
settingsHref = _ref5$settingsHref === void 0 ? "/settings" : _ref5$settingsHref,
|
|
777
|
+
onLogout = _ref5.onLogout;
|
|
778
|
+
var _useState = useState(false),
|
|
779
|
+
isOpen = _useState[0],
|
|
780
|
+
setIsOpen = _useState[1];
|
|
781
|
+
var _useState2 = useState(null),
|
|
782
|
+
fetchedUser = _useState2[0],
|
|
783
|
+
setFetchedUser = _useState2[1];
|
|
784
|
+
var _useState3 = useState(!userProp),
|
|
785
|
+
isLoading = _useState3[0],
|
|
786
|
+
setIsLoading = _useState3[1];
|
|
787
|
+
var router = useRouter();
|
|
788
|
+
var menuRef = useRef(null);
|
|
789
|
+
useEffect(function () {
|
|
790
|
+
var fetchSession = function fetchSession() {
|
|
791
|
+
try {
|
|
792
|
+
var _temp = _finallyRethrows(function () {
|
|
793
|
+
return _catch(function () {
|
|
794
|
+
return Promise.resolve(getAuthJson("api/auth/session", authHost)).then(function (_ref6) {
|
|
795
|
+
var response = _ref6.response,
|
|
796
|
+
data = _ref6.data;
|
|
797
|
+
if (!cancelled && response.ok && data !== null && data !== void 0 && data.user) {
|
|
798
|
+
setFetchedUser(data.user);
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
}, function (err) {
|
|
802
|
+
console.error("Failed to fetch session:", err);
|
|
803
|
+
});
|
|
804
|
+
}, function (_wasThrown, _result) {
|
|
805
|
+
if (!cancelled) setIsLoading(false);
|
|
806
|
+
if (_wasThrown) throw _result;
|
|
807
|
+
return _result;
|
|
808
|
+
});
|
|
809
|
+
return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
|
|
810
|
+
} catch (e) {
|
|
811
|
+
return Promise.reject(e);
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
if (userProp) return;
|
|
815
|
+
var cancelled = false;
|
|
816
|
+
fetchSession();
|
|
817
|
+
return function () {
|
|
818
|
+
cancelled = true;
|
|
819
|
+
};
|
|
820
|
+
}, [authHost, userProp]);
|
|
821
|
+
useEffect(function () {
|
|
822
|
+
function handleClickOutside(e) {
|
|
823
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
824
|
+
setIsOpen(false);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
828
|
+
return function () {
|
|
829
|
+
return document.removeEventListener("mousedown", handleClickOutside);
|
|
830
|
+
};
|
|
831
|
+
}, []);
|
|
832
|
+
var user = userProp || fetchedUser;
|
|
833
|
+
if (isLoading || !user) return null;
|
|
834
|
+
var displayName = user.name || ((_user$email = user.email) === null || _user$email === void 0 ? void 0 : _user$email.split("@")[0]) || "User";
|
|
835
|
+
var initials = getInitials(displayName);
|
|
836
|
+
var avatarColor = getAvatarColor(displayName);
|
|
837
|
+
return React__default.createElement("div", {
|
|
838
|
+
ref: menuRef,
|
|
839
|
+
className: "relative inline-block"
|
|
840
|
+
}, isOpen && React__default.createElement("div", {
|
|
841
|
+
className: "absolute bottom-full mb-1 left-0 z-50 w-52\n bg-white border border-zinc-200\n rounded-xl shadow-lg shadow-zinc-200/50\n overflow-hidden"
|
|
842
|
+
}, React__default.createElement("div", {
|
|
843
|
+
className: "px-3.5 py-3 border-b border-zinc-100"
|
|
844
|
+
}, React__default.createElement("p", {
|
|
845
|
+
className: "text-sm font-medium text-zinc-900 truncate"
|
|
846
|
+
}, displayName), user.email && React__default.createElement("p", {
|
|
847
|
+
className: "text-xs text-zinc-500 truncate mt-0.5"
|
|
848
|
+
}, user.email)), React__default.createElement("div", {
|
|
849
|
+
className: "p-1"
|
|
850
|
+
}, React__default.createElement(Link, {
|
|
851
|
+
href: profileHref,
|
|
852
|
+
onClick: function onClick() {
|
|
853
|
+
return setIsOpen(false);
|
|
854
|
+
},
|
|
855
|
+
className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors"
|
|
856
|
+
}, React__default.createElement(UserIcon, {
|
|
857
|
+
className: "w-4 h-4 text-zinc-400"
|
|
858
|
+
}), "Profile"), React__default.createElement(Link, {
|
|
859
|
+
href: settingsHref,
|
|
860
|
+
onClick: function onClick() {
|
|
861
|
+
return setIsOpen(false);
|
|
862
|
+
},
|
|
863
|
+
className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors"
|
|
864
|
+
}, React__default.createElement(SettingsIcon, {
|
|
865
|
+
className: "w-4 h-4 text-zinc-400"
|
|
866
|
+
}), "Settings"), React__default.createElement("button", {
|
|
867
|
+
onClick: handleLogout,
|
|
868
|
+
className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors text-left"
|
|
869
|
+
}, React__default.createElement(LogOutIcon, {
|
|
870
|
+
className: "w-4 h-4 text-zinc-400"
|
|
871
|
+
}), "Log out"))), React__default.createElement("button", {
|
|
872
|
+
onClick: function onClick() {
|
|
873
|
+
return setIsOpen(function (o) {
|
|
874
|
+
return !o;
|
|
875
|
+
});
|
|
876
|
+
},
|
|
877
|
+
title: displayName,
|
|
878
|
+
className: "flex items-center gap-2.5 p-2 rounded-lg\n hover:bg-zinc-50 transition-colors text-left"
|
|
879
|
+
}, React__default.createElement("div", {
|
|
880
|
+
className: "w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 " + avatarColor
|
|
881
|
+
}, React__default.createElement("span", {
|
|
882
|
+
className: "text-xs font-semibold text-white leading-none"
|
|
883
|
+
}, initials)), React__default.createElement("div", {
|
|
884
|
+
className: "flex-1 min-w-0"
|
|
885
|
+
}, React__default.createElement("p", {
|
|
886
|
+
className: "text-sm font-medium text-zinc-900 truncate leading-tight"
|
|
887
|
+
}, displayName)), React__default.createElement(ChevronsUpDownIcon, {
|
|
888
|
+
className: "w-3.5 h-3.5 text-zinc-400 flex-shrink-0"
|
|
889
|
+
})));
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
export { Hello, Login, OAuthButtons, Signup, UserMenu, VerifyEmail };
|
|
13
893
|
//# sourceMappingURL=index.modern.js.map
|