dauth-context-react 5.0.0 → 6.1.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 +101 -228
- package/dist/index.d.mts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +802 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +807 -96
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -1
- package/src/DauthProfileModal.tsx +890 -0
- package/src/api/dauth.api.ts +6 -17
- package/src/api/interfaces/dauth.api.responses.ts +0 -7
- package/src/api/utils/config.ts +8 -5
- package/src/index.tsx +15 -26
- package/src/initialDauthState.ts +0 -1
- package/src/interfaces.ts +23 -6
- package/src/reducer/dauth.actions.ts +9 -61
package/dist/index.js
CHANGED
|
@@ -20,11 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.tsx
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
DauthProfileModal: () => DauthProfileModal,
|
|
23
24
|
DauthProvider: () => DauthProvider,
|
|
24
25
|
useDauth: () => useDauth
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
var
|
|
28
|
+
var import_react2 = require("react");
|
|
28
29
|
|
|
29
30
|
// src/initialDauthState.ts
|
|
30
31
|
var initialDauthState = {
|
|
@@ -39,8 +40,6 @@ var initialDauthState = {
|
|
|
39
40
|
logout: () => {
|
|
40
41
|
},
|
|
41
42
|
updateUser: () => Promise.resolve(false),
|
|
42
|
-
updateUserWithRedirect: () => {
|
|
43
|
-
},
|
|
44
43
|
deleteAccount: () => Promise.resolve(false)
|
|
45
44
|
};
|
|
46
45
|
var initialDauthState_default = initialDauthState;
|
|
@@ -90,7 +89,12 @@ function getCsrfToken() {
|
|
|
90
89
|
const match = document.cookie.match(
|
|
91
90
|
/(?:^|;\s*)(?:__Host-csrf|csrf-token)=([^;]*)/
|
|
92
91
|
);
|
|
93
|
-
|
|
92
|
+
if (!match?.[1]) return "";
|
|
93
|
+
try {
|
|
94
|
+
return decodeURIComponent(match[1]);
|
|
95
|
+
} catch {
|
|
96
|
+
return match[1];
|
|
97
|
+
}
|
|
94
98
|
}
|
|
95
99
|
async function exchangeCodeAPI(basePath, code) {
|
|
96
100
|
const response = await fetch(`${basePath}/exchange-code`, {
|
|
@@ -143,18 +147,6 @@ async function deleteAccountAPI(basePath) {
|
|
|
143
147
|
const data = await response.json();
|
|
144
148
|
return { response, data };
|
|
145
149
|
}
|
|
146
|
-
async function profileRedirectAPI(basePath) {
|
|
147
|
-
const response = await fetch(
|
|
148
|
-
`${basePath}/profile-redirect`,
|
|
149
|
-
{
|
|
150
|
-
method: "GET",
|
|
151
|
-
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
152
|
-
credentials: "include"
|
|
153
|
-
}
|
|
154
|
-
);
|
|
155
|
-
const data = await response.json();
|
|
156
|
-
return { response, data };
|
|
157
|
-
}
|
|
158
150
|
|
|
159
151
|
// src/reducer/dauth.actions.ts
|
|
160
152
|
async function exchangeCodeAction(ctx, code) {
|
|
@@ -164,11 +156,7 @@ async function exchangeCodeAction(ctx, code) {
|
|
|
164
156
|
payload: { isLoading: true }
|
|
165
157
|
});
|
|
166
158
|
try {
|
|
167
|
-
window.history.replaceState(
|
|
168
|
-
{},
|
|
169
|
-
document.title,
|
|
170
|
-
window.location.pathname
|
|
171
|
-
);
|
|
159
|
+
window.history.replaceState({}, document.title, window.location.pathname);
|
|
172
160
|
const result = await exchangeCodeAPI(authProxyPath, code);
|
|
173
161
|
if (result.response.status === 200) {
|
|
174
162
|
dispatch({
|
|
@@ -183,9 +171,7 @@ async function exchangeCodeAction(ctx, code) {
|
|
|
183
171
|
}
|
|
184
172
|
resetUser(dispatch);
|
|
185
173
|
} catch (error) {
|
|
186
|
-
onError(
|
|
187
|
-
error instanceof Error ? error : new Error(String(error))
|
|
188
|
-
);
|
|
174
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
189
175
|
resetUser(dispatch);
|
|
190
176
|
} finally {
|
|
191
177
|
dispatch({
|
|
@@ -215,9 +201,7 @@ async function autoLoginAction(ctx) {
|
|
|
215
201
|
}
|
|
216
202
|
resetUser(dispatch);
|
|
217
203
|
} catch (error) {
|
|
218
|
-
onError(
|
|
219
|
-
error instanceof Error ? error : new Error(String(error))
|
|
220
|
-
);
|
|
204
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
221
205
|
resetUser(dispatch);
|
|
222
206
|
} finally {
|
|
223
207
|
dispatch({
|
|
@@ -254,10 +238,7 @@ async function logoutAction(ctx) {
|
|
|
254
238
|
async function updateUserAction(ctx, user) {
|
|
255
239
|
const { dispatch, authProxyPath, onError } = ctx;
|
|
256
240
|
if (user.language) {
|
|
257
|
-
window.document.documentElement.setAttribute(
|
|
258
|
-
"lang",
|
|
259
|
-
user.language
|
|
260
|
-
);
|
|
241
|
+
window.document.documentElement.setAttribute("lang", user.language);
|
|
261
242
|
}
|
|
262
243
|
try {
|
|
263
244
|
const result = await updateUserAPI(authProxyPath, user);
|
|
@@ -268,34 +249,13 @@ async function updateUserAction(ctx, user) {
|
|
|
268
249
|
});
|
|
269
250
|
return true;
|
|
270
251
|
}
|
|
271
|
-
onError(
|
|
272
|
-
new Error("Update user error: " + result.data.message)
|
|
273
|
-
);
|
|
252
|
+
onError(new Error("Update user error: " + result.data.message));
|
|
274
253
|
return false;
|
|
275
254
|
} catch (error) {
|
|
276
|
-
onError(
|
|
277
|
-
error instanceof Error ? error : new Error("Update user error")
|
|
278
|
-
);
|
|
255
|
+
onError(error instanceof Error ? error : new Error("Update user error"));
|
|
279
256
|
return false;
|
|
280
257
|
}
|
|
281
258
|
}
|
|
282
|
-
async function updateUserWithRedirectAction(ctx) {
|
|
283
|
-
const { authProxyPath, onError } = ctx;
|
|
284
|
-
try {
|
|
285
|
-
const result = await profileRedirectAPI(authProxyPath);
|
|
286
|
-
if (result.response.status === 200 && result.data.redirectUrl) {
|
|
287
|
-
window.location.replace(result.data.redirectUrl);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
onError(
|
|
291
|
-
new Error("Could not generate profile redirect")
|
|
292
|
-
);
|
|
293
|
-
} catch (error) {
|
|
294
|
-
onError(
|
|
295
|
-
error instanceof Error ? error : new Error("Profile redirect error")
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
259
|
async function deleteAccountAction(ctx) {
|
|
300
260
|
const { dispatch, authProxyPath, onError } = ctx;
|
|
301
261
|
try {
|
|
@@ -306,9 +266,7 @@ async function deleteAccountAction(ctx) {
|
|
|
306
266
|
}
|
|
307
267
|
return false;
|
|
308
268
|
} catch (error) {
|
|
309
|
-
onError(
|
|
310
|
-
error instanceof Error ? error : new Error("Delete account error")
|
|
311
|
-
);
|
|
269
|
+
onError(error instanceof Error ? error : new Error("Delete account error"));
|
|
312
270
|
return false;
|
|
313
271
|
}
|
|
314
272
|
}
|
|
@@ -332,12 +290,12 @@ function setDauthUrl(url) {
|
|
|
332
290
|
function checkIsLocalhost() {
|
|
333
291
|
if (typeof window === "undefined") return false;
|
|
334
292
|
const hostname = window.location.hostname;
|
|
335
|
-
return
|
|
336
|
-
hostname
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
293
|
+
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
294
|
+
hostname
|
|
295
|
+
) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
|
|
296
|
+
hostname
|
|
297
|
+
) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
298
|
+
hostname
|
|
341
299
|
);
|
|
342
300
|
}
|
|
343
301
|
function getClientBasePath() {
|
|
@@ -357,8 +315,773 @@ var routes = {
|
|
|
357
315
|
signin: "signin"
|
|
358
316
|
};
|
|
359
317
|
|
|
360
|
-
// src/
|
|
318
|
+
// src/DauthProfileModal.tsx
|
|
319
|
+
var import_react = require("react");
|
|
320
|
+
var import_react_dom = require("react-dom");
|
|
361
321
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
322
|
+
var TRANSITION_MS = 200;
|
|
323
|
+
var MOBILE_TRANSITION_MS = 300;
|
|
324
|
+
var SUCCESS_TIMEOUT_MS = 4e3;
|
|
325
|
+
var CONFIRM_WORD = "DELETE";
|
|
326
|
+
function IconClose() {
|
|
327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
328
|
+
"svg",
|
|
329
|
+
{
|
|
330
|
+
width: "20",
|
|
331
|
+
height: "20",
|
|
332
|
+
viewBox: "0 0 24 24",
|
|
333
|
+
fill: "none",
|
|
334
|
+
stroke: "currentColor",
|
|
335
|
+
strokeWidth: "2",
|
|
336
|
+
strokeLinecap: "round",
|
|
337
|
+
strokeLinejoin: "round",
|
|
338
|
+
children: [
|
|
339
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
340
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
function IconBack() {
|
|
346
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
347
|
+
"svg",
|
|
348
|
+
{
|
|
349
|
+
width: "20",
|
|
350
|
+
height: "20",
|
|
351
|
+
viewBox: "0 0 24 24",
|
|
352
|
+
fill: "none",
|
|
353
|
+
stroke: "currentColor",
|
|
354
|
+
strokeWidth: "2",
|
|
355
|
+
strokeLinecap: "round",
|
|
356
|
+
strokeLinejoin: "round",
|
|
357
|
+
children: [
|
|
358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
|
|
359
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "12 19 5 12 12 5" })
|
|
360
|
+
]
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
function Spinner() {
|
|
365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: spinnerStyle, "aria-hidden": "true" });
|
|
366
|
+
}
|
|
367
|
+
function useMediaQuery(query) {
|
|
368
|
+
const [matches, setMatches] = (0, import_react.useState)(
|
|
369
|
+
() => typeof window !== "undefined" && window.matchMedia(query).matches
|
|
370
|
+
);
|
|
371
|
+
(0, import_react.useEffect)(() => {
|
|
372
|
+
const mq = window.matchMedia(query);
|
|
373
|
+
const handler = (e) => setMatches(e.matches);
|
|
374
|
+
mq.addEventListener("change", handler);
|
|
375
|
+
return () => mq.removeEventListener("change", handler);
|
|
376
|
+
}, [query]);
|
|
377
|
+
return matches;
|
|
378
|
+
}
|
|
379
|
+
function useModalAnimation(open) {
|
|
380
|
+
const [phase, setPhase] = (0, import_react.useState)("exited");
|
|
381
|
+
(0, import_react.useEffect)(() => {
|
|
382
|
+
if (open) {
|
|
383
|
+
setPhase("entering");
|
|
384
|
+
const raf = requestAnimationFrame(() => {
|
|
385
|
+
requestAnimationFrame(() => setPhase("entered"));
|
|
386
|
+
});
|
|
387
|
+
return () => cancelAnimationFrame(raf);
|
|
388
|
+
}
|
|
389
|
+
if (phase === "entered" || phase === "entering") {
|
|
390
|
+
setPhase("exiting");
|
|
391
|
+
const timer = setTimeout(() => setPhase("exited"), MOBILE_TRANSITION_MS);
|
|
392
|
+
return () => clearTimeout(timer);
|
|
393
|
+
}
|
|
394
|
+
return void 0;
|
|
395
|
+
}, [open]);
|
|
396
|
+
return phase;
|
|
397
|
+
}
|
|
398
|
+
function useFocusTrap(containerRef, active, onEscape) {
|
|
399
|
+
const previousFocus = (0, import_react.useRef)(null);
|
|
400
|
+
(0, import_react.useEffect)(() => {
|
|
401
|
+
if (!active) return;
|
|
402
|
+
previousFocus.current = document.activeElement;
|
|
403
|
+
const container = containerRef.current;
|
|
404
|
+
if (!container) return;
|
|
405
|
+
const focusFirst = () => {
|
|
406
|
+
const firstInput = container.querySelector(
|
|
407
|
+
"input:not([disabled])"
|
|
408
|
+
);
|
|
409
|
+
(firstInput ?? container).focus();
|
|
410
|
+
};
|
|
411
|
+
const raf = requestAnimationFrame(focusFirst);
|
|
412
|
+
const handleKeyDown = (e) => {
|
|
413
|
+
if (e.key === "Escape") {
|
|
414
|
+
e.preventDefault();
|
|
415
|
+
onEscape();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (e.key !== "Tab") return;
|
|
419
|
+
const focusable = container.querySelectorAll(
|
|
420
|
+
'button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
421
|
+
);
|
|
422
|
+
if (focusable.length === 0) return;
|
|
423
|
+
const first = focusable[0];
|
|
424
|
+
const last = focusable[focusable.length - 1];
|
|
425
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
426
|
+
e.preventDefault();
|
|
427
|
+
last.focus();
|
|
428
|
+
} else if (!e.shiftKey && document.activeElement === last) {
|
|
429
|
+
e.preventDefault();
|
|
430
|
+
first.focus();
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
434
|
+
return () => {
|
|
435
|
+
cancelAnimationFrame(raf);
|
|
436
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
437
|
+
if (previousFocus.current instanceof HTMLElement) {
|
|
438
|
+
previousFocus.current.focus();
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}, [active, containerRef, onEscape]);
|
|
442
|
+
}
|
|
443
|
+
function useScrollLock(active) {
|
|
444
|
+
(0, import_react.useEffect)(() => {
|
|
445
|
+
if (!active) return;
|
|
446
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
447
|
+
const prevOverflow = document.body.style.overflow;
|
|
448
|
+
const prevPaddingRight = document.body.style.paddingRight;
|
|
449
|
+
document.body.style.overflow = "hidden";
|
|
450
|
+
if (scrollbarWidth > 0) {
|
|
451
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
452
|
+
}
|
|
453
|
+
return () => {
|
|
454
|
+
document.body.style.overflow = prevOverflow;
|
|
455
|
+
document.body.style.paddingRight = prevPaddingRight;
|
|
456
|
+
};
|
|
457
|
+
}, [active]);
|
|
458
|
+
}
|
|
459
|
+
function DauthProfileModal({ open, onClose }) {
|
|
460
|
+
const { user, domain, updateUser, deleteAccount } = useDauth();
|
|
461
|
+
const isDesktop = useMediaQuery("(min-width: 641px)");
|
|
462
|
+
const phase = useModalAnimation(open);
|
|
463
|
+
const modalRef = (0, import_react.useRef)(null);
|
|
464
|
+
const [name, setName] = (0, import_react.useState)("");
|
|
465
|
+
const [lastname, setLastname] = (0, import_react.useState)("");
|
|
466
|
+
const [nickname, setNickname] = (0, import_react.useState)("");
|
|
467
|
+
const [country, setCountry] = (0, import_react.useState)("");
|
|
468
|
+
const [populated, setPopulated] = (0, import_react.useState)(false);
|
|
469
|
+
const [saving, setSaving] = (0, import_react.useState)(false);
|
|
470
|
+
const [status, setStatus] = (0, import_react.useState)(null);
|
|
471
|
+
const [showDelete, setShowDelete] = (0, import_react.useState)(false);
|
|
472
|
+
const [deleteText, setDeleteText] = (0, import_react.useState)("");
|
|
473
|
+
const [deleting, setDeleting] = (0, import_react.useState)(false);
|
|
474
|
+
(0, import_react.useEffect)(() => {
|
|
475
|
+
if (open && user?._id && !populated) {
|
|
476
|
+
setName(user.name || "");
|
|
477
|
+
setLastname(user.lastname || "");
|
|
478
|
+
setNickname(user.nickname || "");
|
|
479
|
+
setCountry(user.country || "");
|
|
480
|
+
setPopulated(true);
|
|
481
|
+
}
|
|
482
|
+
if (!open) {
|
|
483
|
+
setPopulated(false);
|
|
484
|
+
setStatus(null);
|
|
485
|
+
setShowDelete(false);
|
|
486
|
+
setDeleteText("");
|
|
487
|
+
}
|
|
488
|
+
}, [open, user, populated]);
|
|
489
|
+
(0, import_react.useEffect)(() => {
|
|
490
|
+
if (status?.type !== "success") return;
|
|
491
|
+
const timer = setTimeout(() => setStatus(null), SUCCESS_TIMEOUT_MS);
|
|
492
|
+
return () => clearTimeout(timer);
|
|
493
|
+
}, [status]);
|
|
494
|
+
useFocusTrap(modalRef, phase === "entered", onClose);
|
|
495
|
+
useScrollLock(phase !== "exited");
|
|
496
|
+
const hasField = (0, import_react.useCallback)(
|
|
497
|
+
(field) => domain.formFields?.some((f) => f.field === field) ?? false,
|
|
498
|
+
[domain.formFields]
|
|
499
|
+
);
|
|
500
|
+
const isRequired = (0, import_react.useCallback)(
|
|
501
|
+
(field) => domain.formFields?.find((f) => f.field === field)?.required ?? false,
|
|
502
|
+
[domain.formFields]
|
|
503
|
+
);
|
|
504
|
+
const hasChanges = (0, import_react.useMemo)(() => {
|
|
505
|
+
if (!user?._id) return false;
|
|
506
|
+
return name !== (user.name || "") || lastname !== (user.lastname || "") || nickname !== (user.nickname || "") || country !== (user.country || "");
|
|
507
|
+
}, [name, lastname, nickname, country, user]);
|
|
508
|
+
const canSave = name.trim().length > 0 && hasChanges && !saving;
|
|
509
|
+
const handleSave = (0, import_react.useCallback)(async () => {
|
|
510
|
+
setSaving(true);
|
|
511
|
+
setStatus(null);
|
|
512
|
+
const fields = { name };
|
|
513
|
+
if (hasField("lastname")) fields.lastname = lastname;
|
|
514
|
+
if (hasField("nickname")) fields.nickname = nickname;
|
|
515
|
+
if (hasField("country")) fields.country = country;
|
|
516
|
+
const ok = await updateUser(fields);
|
|
517
|
+
setSaving(false);
|
|
518
|
+
if (ok) {
|
|
519
|
+
setStatus({
|
|
520
|
+
type: "success",
|
|
521
|
+
message: "Profile updated successfully"
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
setStatus({
|
|
525
|
+
type: "error",
|
|
526
|
+
message: "Something went wrong. Please try again."
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
}, [name, lastname, nickname, country, hasField, updateUser]);
|
|
530
|
+
const handleDelete = (0, import_react.useCallback)(async () => {
|
|
531
|
+
setDeleting(true);
|
|
532
|
+
const ok = await deleteAccount();
|
|
533
|
+
setDeleting(false);
|
|
534
|
+
if (ok) {
|
|
535
|
+
onClose();
|
|
536
|
+
} else {
|
|
537
|
+
setStatus({
|
|
538
|
+
type: "error",
|
|
539
|
+
message: "Could not delete account. Please try again."
|
|
540
|
+
});
|
|
541
|
+
setShowDelete(false);
|
|
542
|
+
setDeleteText("");
|
|
543
|
+
}
|
|
544
|
+
}, [deleteAccount, onClose]);
|
|
545
|
+
const themeVars = (0, import_react.useMemo)(() => {
|
|
546
|
+
const t = domain.modalTheme;
|
|
547
|
+
if (!t) return {};
|
|
548
|
+
const vars = {};
|
|
549
|
+
if (t.accent) vars["--dauth-accent"] = t.accent;
|
|
550
|
+
if (t.accentHover) vars["--dauth-accent-hover"] = t.accentHover;
|
|
551
|
+
if (t.surface) vars["--dauth-surface"] = t.surface;
|
|
552
|
+
if (t.surfaceHover) vars["--dauth-surface-hover"] = t.surfaceHover;
|
|
553
|
+
if (t.textPrimary) vars["--dauth-text-primary"] = t.textPrimary;
|
|
554
|
+
if (t.textSecondary) vars["--dauth-text-secondary"] = t.textSecondary;
|
|
555
|
+
if (t.border) vars["--dauth-border"] = t.border;
|
|
556
|
+
return vars;
|
|
557
|
+
}, [domain.modalTheme]);
|
|
558
|
+
if (phase === "exited") return null;
|
|
559
|
+
const dur = isDesktop ? TRANSITION_MS : MOBILE_TRANSITION_MS;
|
|
560
|
+
const easing = "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
561
|
+
const backdrop = {
|
|
562
|
+
position: "fixed",
|
|
563
|
+
inset: 0,
|
|
564
|
+
zIndex: 2147483647,
|
|
565
|
+
backgroundColor: "var(--dauth-backdrop, rgba(0, 0, 0, 0.6))",
|
|
566
|
+
backdropFilter: "blur(4px)",
|
|
567
|
+
WebkitBackdropFilter: "blur(4px)",
|
|
568
|
+
display: "flex",
|
|
569
|
+
alignItems: "center",
|
|
570
|
+
justifyContent: "center",
|
|
571
|
+
opacity: phase === "entered" ? 1 : 0,
|
|
572
|
+
transition: `opacity ${dur}ms ease-out`
|
|
573
|
+
};
|
|
574
|
+
const modalDesktop = {
|
|
575
|
+
position: "relative",
|
|
576
|
+
width: "100%",
|
|
577
|
+
maxWidth: 480,
|
|
578
|
+
maxHeight: "90vh",
|
|
579
|
+
margin: 16,
|
|
580
|
+
backgroundColor: "var(--dauth-surface, #1a1a2e)",
|
|
581
|
+
borderRadius: "var(--dauth-radius, 12px)",
|
|
582
|
+
boxShadow: "var(--dauth-shadow, 0 25px 50px -12px rgba(0, 0, 0, 0.5))",
|
|
583
|
+
border: "1px solid var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
584
|
+
display: "flex",
|
|
585
|
+
flexDirection: "column",
|
|
586
|
+
overflow: "hidden",
|
|
587
|
+
fontFamily: "var(--dauth-font-family, system-ui, -apple-system, sans-serif)",
|
|
588
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
589
|
+
opacity: phase === "entered" ? 1 : 0,
|
|
590
|
+
transform: phase === "entered" ? "translateY(0)" : "translateY(16px)",
|
|
591
|
+
transition: `opacity ${dur}ms ${easing}, transform ${dur}ms ${easing}`
|
|
592
|
+
};
|
|
593
|
+
const modalMobile = {
|
|
594
|
+
position: "fixed",
|
|
595
|
+
inset: 0,
|
|
596
|
+
backgroundColor: "var(--dauth-surface, #1a1a2e)",
|
|
597
|
+
display: "flex",
|
|
598
|
+
flexDirection: "column",
|
|
599
|
+
fontFamily: "var(--dauth-font-family, system-ui, -apple-system, sans-serif)",
|
|
600
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
601
|
+
transform: phase === "entered" ? "translateY(0)" : "translateY(100%)",
|
|
602
|
+
transition: `transform ${dur}ms ${easing}`
|
|
603
|
+
};
|
|
604
|
+
const avatarInitial = (user.name || user.email || "?").charAt(0).toUpperCase();
|
|
605
|
+
return (0, import_react_dom.createPortal)(
|
|
606
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
607
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
608
|
+
"style",
|
|
609
|
+
{
|
|
610
|
+
dangerouslySetInnerHTML: {
|
|
611
|
+
__html: "@keyframes dauth-spin{to{transform:rotate(360deg)}}"
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
),
|
|
615
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
616
|
+
"div",
|
|
617
|
+
{
|
|
618
|
+
style: { ...backdrop, ...themeVars },
|
|
619
|
+
onClick: isDesktop ? onClose : void 0,
|
|
620
|
+
"data-testid": "dauth-profile-backdrop",
|
|
621
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
622
|
+
"div",
|
|
623
|
+
{
|
|
624
|
+
ref: modalRef,
|
|
625
|
+
role: "dialog",
|
|
626
|
+
"aria-modal": "true",
|
|
627
|
+
"aria-labelledby": "dauth-profile-title",
|
|
628
|
+
style: isDesktop ? modalDesktop : modalMobile,
|
|
629
|
+
onClick: (e) => e.stopPropagation(),
|
|
630
|
+
tabIndex: -1,
|
|
631
|
+
children: [
|
|
632
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: headerStyle(isDesktop), children: [
|
|
633
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
634
|
+
"button",
|
|
635
|
+
{
|
|
636
|
+
type: "button",
|
|
637
|
+
onClick: onClose,
|
|
638
|
+
style: closeBtn,
|
|
639
|
+
"aria-label": "Close",
|
|
640
|
+
onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "var(--dauth-surface-hover, #232340)",
|
|
641
|
+
onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
|
|
642
|
+
children: isDesktop ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconClose, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBack, {})
|
|
643
|
+
}
|
|
644
|
+
),
|
|
645
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: "dauth-profile-title", style: titleStyle, children: "Your Profile" }),
|
|
646
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width: 36 } })
|
|
647
|
+
] }),
|
|
648
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: bodyStyle, children: [
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: avatarSection, children: [
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: avatarCircle, children: user.avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
651
|
+
"img",
|
|
652
|
+
{
|
|
653
|
+
src: user.avatar.url,
|
|
654
|
+
alt: "",
|
|
655
|
+
style: {
|
|
656
|
+
width: "100%",
|
|
657
|
+
height: "100%",
|
|
658
|
+
objectFit: "cover"
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
) : avatarInitial }),
|
|
662
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: emailText, children: user.email })
|
|
663
|
+
] }),
|
|
664
|
+
status && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
665
|
+
"div",
|
|
666
|
+
{
|
|
667
|
+
role: "status",
|
|
668
|
+
"aria-live": "polite",
|
|
669
|
+
style: statusMsg(status.type),
|
|
670
|
+
children: status.message
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
674
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "dauth-name", style: label, children: "Name *" }),
|
|
676
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
677
|
+
"input",
|
|
678
|
+
{
|
|
679
|
+
id: "dauth-name",
|
|
680
|
+
type: "text",
|
|
681
|
+
value: name,
|
|
682
|
+
onChange: (e) => setName(e.target.value),
|
|
683
|
+
placeholder: "Your name",
|
|
684
|
+
disabled: saving,
|
|
685
|
+
style: input,
|
|
686
|
+
onFocus: inputFocusHandler,
|
|
687
|
+
onBlur: inputBlurHandler
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
] }),
|
|
691
|
+
hasField("lastname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-lastname", style: label, children: [
|
|
693
|
+
"Last name",
|
|
694
|
+
isRequired("lastname") ? " *" : ""
|
|
695
|
+
] }),
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
697
|
+
"input",
|
|
698
|
+
{
|
|
699
|
+
id: "dauth-lastname",
|
|
700
|
+
type: "text",
|
|
701
|
+
value: lastname,
|
|
702
|
+
onChange: (e) => setLastname(e.target.value),
|
|
703
|
+
placeholder: "Your last name",
|
|
704
|
+
disabled: saving,
|
|
705
|
+
style: input,
|
|
706
|
+
onFocus: inputFocusHandler,
|
|
707
|
+
onBlur: inputBlurHandler
|
|
708
|
+
}
|
|
709
|
+
)
|
|
710
|
+
] }),
|
|
711
|
+
hasField("nickname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-nickname", style: label, children: [
|
|
713
|
+
"Nickname",
|
|
714
|
+
isRequired("nickname") ? " *" : ""
|
|
715
|
+
] }),
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
717
|
+
"input",
|
|
718
|
+
{
|
|
719
|
+
id: "dauth-nickname",
|
|
720
|
+
type: "text",
|
|
721
|
+
value: nickname,
|
|
722
|
+
onChange: (e) => setNickname(e.target.value),
|
|
723
|
+
placeholder: "Choose a nickname",
|
|
724
|
+
disabled: saving,
|
|
725
|
+
style: input,
|
|
726
|
+
onFocus: inputFocusHandler,
|
|
727
|
+
onBlur: inputBlurHandler
|
|
728
|
+
}
|
|
729
|
+
)
|
|
730
|
+
] }),
|
|
731
|
+
hasField("country") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-country", style: label, children: [
|
|
733
|
+
"Country",
|
|
734
|
+
isRequired("country") ? " *" : ""
|
|
735
|
+
] }),
|
|
736
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
737
|
+
"input",
|
|
738
|
+
{
|
|
739
|
+
id: "dauth-country",
|
|
740
|
+
type: "text",
|
|
741
|
+
value: country,
|
|
742
|
+
onChange: (e) => setCountry(e.target.value),
|
|
743
|
+
placeholder: "Your country",
|
|
744
|
+
disabled: saving,
|
|
745
|
+
style: input,
|
|
746
|
+
onFocus: inputFocusHandler,
|
|
747
|
+
onBlur: inputBlurHandler
|
|
748
|
+
}
|
|
749
|
+
)
|
|
750
|
+
] })
|
|
751
|
+
] }),
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: separator }),
|
|
753
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
754
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: dangerTitle, children: "Delete account" }),
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: dangerDesc, children: "Permanently delete your account and all associated data." }),
|
|
756
|
+
!showDelete ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
757
|
+
"button",
|
|
758
|
+
{
|
|
759
|
+
type: "button",
|
|
760
|
+
style: deleteBtn,
|
|
761
|
+
onClick: () => setShowDelete(true),
|
|
762
|
+
onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(239, 68, 68, 0.2)",
|
|
763
|
+
onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "var(--dauth-error-bg, rgba(239, 68, 68, 0.1))",
|
|
764
|
+
children: "Delete account"
|
|
765
|
+
}
|
|
766
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: deletePanel, children: [
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: deletePanelText, children: [
|
|
768
|
+
"This action is permanent and cannot be undone. Type",
|
|
769
|
+
" ",
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: CONFIRM_WORD }),
|
|
771
|
+
" to confirm."
|
|
772
|
+
] }),
|
|
773
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
774
|
+
"input",
|
|
775
|
+
{
|
|
776
|
+
type: "text",
|
|
777
|
+
value: deleteText,
|
|
778
|
+
onChange: (e) => setDeleteText(e.target.value),
|
|
779
|
+
placeholder: `Type ${CONFIRM_WORD}`,
|
|
780
|
+
style: input,
|
|
781
|
+
onFocus: inputFocusHandler,
|
|
782
|
+
onBlur: inputBlurHandler,
|
|
783
|
+
disabled: deleting
|
|
784
|
+
}
|
|
785
|
+
),
|
|
786
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
787
|
+
"div",
|
|
788
|
+
{
|
|
789
|
+
style: {
|
|
790
|
+
display: "flex",
|
|
791
|
+
gap: 8,
|
|
792
|
+
marginTop: 12
|
|
793
|
+
},
|
|
794
|
+
children: [
|
|
795
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
796
|
+
"button",
|
|
797
|
+
{
|
|
798
|
+
type: "button",
|
|
799
|
+
style: cancelBtn,
|
|
800
|
+
onClick: () => {
|
|
801
|
+
setShowDelete(false);
|
|
802
|
+
setDeleteText("");
|
|
803
|
+
},
|
|
804
|
+
onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "var(--dauth-surface-hover, #232340)",
|
|
805
|
+
onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
|
|
806
|
+
children: "Cancel"
|
|
807
|
+
}
|
|
808
|
+
),
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
810
|
+
"button",
|
|
811
|
+
{
|
|
812
|
+
type: "button",
|
|
813
|
+
style: {
|
|
814
|
+
...deleteConfirmBtn,
|
|
815
|
+
opacity: deleteText !== CONFIRM_WORD || deleting ? 0.5 : 1,
|
|
816
|
+
cursor: deleteText !== CONFIRM_WORD || deleting ? "not-allowed" : "pointer"
|
|
817
|
+
},
|
|
818
|
+
disabled: deleteText !== CONFIRM_WORD || deleting,
|
|
819
|
+
onClick: handleDelete,
|
|
820
|
+
children: [
|
|
821
|
+
deleting && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}),
|
|
822
|
+
"Delete my account"
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
)
|
|
826
|
+
]
|
|
827
|
+
}
|
|
828
|
+
)
|
|
829
|
+
] })
|
|
830
|
+
] })
|
|
831
|
+
] }),
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: footerStyle(isDesktop), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
833
|
+
"button",
|
|
834
|
+
{
|
|
835
|
+
type: "button",
|
|
836
|
+
style: {
|
|
837
|
+
...saveBtn,
|
|
838
|
+
opacity: canSave ? 1 : 0.5,
|
|
839
|
+
cursor: canSave ? "pointer" : "not-allowed"
|
|
840
|
+
},
|
|
841
|
+
disabled: !canSave,
|
|
842
|
+
onClick: handleSave,
|
|
843
|
+
"aria-busy": saving,
|
|
844
|
+
onMouseEnter: (e) => {
|
|
845
|
+
if (canSave)
|
|
846
|
+
e.currentTarget.style.backgroundColor = "var(--dauth-accent-hover, #818cf8)";
|
|
847
|
+
},
|
|
848
|
+
onMouseLeave: (e) => {
|
|
849
|
+
e.currentTarget.style.backgroundColor = "var(--dauth-accent, #6366f1)";
|
|
850
|
+
},
|
|
851
|
+
children: [
|
|
852
|
+
saving && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}),
|
|
853
|
+
saving ? "Saving..." : "Save changes"
|
|
854
|
+
]
|
|
855
|
+
}
|
|
856
|
+
) })
|
|
857
|
+
]
|
|
858
|
+
}
|
|
859
|
+
)
|
|
860
|
+
}
|
|
861
|
+
)
|
|
862
|
+
] }),
|
|
863
|
+
document.body
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
var headerStyle = (isDesktop) => ({
|
|
867
|
+
display: "flex",
|
|
868
|
+
alignItems: "center",
|
|
869
|
+
justifyContent: "space-between",
|
|
870
|
+
padding: "16px 24px",
|
|
871
|
+
borderBottom: "1px solid var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
872
|
+
flexShrink: 0,
|
|
873
|
+
...!isDesktop ? {
|
|
874
|
+
position: "sticky",
|
|
875
|
+
top: 0,
|
|
876
|
+
zIndex: 1,
|
|
877
|
+
backgroundColor: "var(--dauth-surface, #1a1a2e)"
|
|
878
|
+
} : {}
|
|
879
|
+
});
|
|
880
|
+
var titleStyle = {
|
|
881
|
+
fontSize: "var(--dauth-font-size-lg, 1.25rem)",
|
|
882
|
+
fontWeight: 600,
|
|
883
|
+
margin: 0,
|
|
884
|
+
lineHeight: 1.4,
|
|
885
|
+
textAlign: "center",
|
|
886
|
+
flex: 1
|
|
887
|
+
};
|
|
888
|
+
var closeBtn = {
|
|
889
|
+
display: "flex",
|
|
890
|
+
alignItems: "center",
|
|
891
|
+
justifyContent: "center",
|
|
892
|
+
width: 36,
|
|
893
|
+
height: 36,
|
|
894
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
895
|
+
border: "none",
|
|
896
|
+
backgroundColor: "transparent",
|
|
897
|
+
color: "var(--dauth-text-secondary, #a1a1aa)",
|
|
898
|
+
cursor: "pointer",
|
|
899
|
+
transition: "background-color 150ms, color 150ms",
|
|
900
|
+
padding: 0
|
|
901
|
+
};
|
|
902
|
+
var bodyStyle = {
|
|
903
|
+
flex: 1,
|
|
904
|
+
overflowY: "auto",
|
|
905
|
+
padding: 24,
|
|
906
|
+
WebkitOverflowScrolling: "touch"
|
|
907
|
+
};
|
|
908
|
+
var avatarSection = {
|
|
909
|
+
display: "flex",
|
|
910
|
+
flexDirection: "column",
|
|
911
|
+
alignItems: "center",
|
|
912
|
+
marginBottom: 24,
|
|
913
|
+
gap: 8
|
|
914
|
+
};
|
|
915
|
+
var avatarCircle = {
|
|
916
|
+
width: 64,
|
|
917
|
+
height: 64,
|
|
918
|
+
borderRadius: "50%",
|
|
919
|
+
backgroundColor: "var(--dauth-accent, #6366f1)",
|
|
920
|
+
display: "flex",
|
|
921
|
+
alignItems: "center",
|
|
922
|
+
justifyContent: "center",
|
|
923
|
+
overflow: "hidden",
|
|
924
|
+
color: "#ffffff",
|
|
925
|
+
fontSize: "1.5rem",
|
|
926
|
+
fontWeight: 600
|
|
927
|
+
};
|
|
928
|
+
var emailText = {
|
|
929
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
930
|
+
color: "var(--dauth-text-secondary, #a1a1aa)"
|
|
931
|
+
};
|
|
932
|
+
var statusMsg = (type) => ({
|
|
933
|
+
padding: "10px 14px",
|
|
934
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
935
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
936
|
+
marginBottom: 16,
|
|
937
|
+
backgroundColor: type === "success" ? "var(--dauth-success-bg, rgba(34, 197, 94, 0.1))" : "var(--dauth-error-bg, rgba(239, 68, 68, 0.1))",
|
|
938
|
+
color: type === "success" ? "var(--dauth-success, #22c55e)" : "var(--dauth-error, #ef4444)",
|
|
939
|
+
textAlign: "center",
|
|
940
|
+
lineHeight: 1.5
|
|
941
|
+
});
|
|
942
|
+
var fieldGroup = { marginBottom: 16 };
|
|
943
|
+
var label = {
|
|
944
|
+
display: "block",
|
|
945
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
946
|
+
fontWeight: 500,
|
|
947
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
948
|
+
marginBottom: 6
|
|
949
|
+
};
|
|
950
|
+
var input = {
|
|
951
|
+
width: "100%",
|
|
952
|
+
padding: "10px 14px",
|
|
953
|
+
fontSize: "var(--dauth-font-size-base, 1rem)",
|
|
954
|
+
lineHeight: 1.5,
|
|
955
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
956
|
+
backgroundColor: "var(--dauth-surface-secondary, rgba(255, 255, 255, 0.04))",
|
|
957
|
+
border: "1px solid var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
958
|
+
borderRadius: "var(--dauth-radius-input, 8px)",
|
|
959
|
+
outline: "none",
|
|
960
|
+
transition: "border-color 150ms, box-shadow 150ms",
|
|
961
|
+
boxSizing: "border-box",
|
|
962
|
+
fontFamily: "inherit"
|
|
963
|
+
};
|
|
964
|
+
var inputFocusHandler = (e) => {
|
|
965
|
+
e.currentTarget.style.borderColor = "var(--dauth-border-focus, rgba(99, 102, 241, 0.5))";
|
|
966
|
+
e.currentTarget.style.boxShadow = "0 0 0 3px rgba(99, 102, 241, 0.15)";
|
|
967
|
+
};
|
|
968
|
+
var inputBlurHandler = (e) => {
|
|
969
|
+
e.currentTarget.style.borderColor = "var(--dauth-border, rgba(255, 255, 255, 0.08))";
|
|
970
|
+
e.currentTarget.style.boxShadow = "none";
|
|
971
|
+
};
|
|
972
|
+
var separator = {
|
|
973
|
+
height: 1,
|
|
974
|
+
backgroundColor: "var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
975
|
+
margin: "24px 0",
|
|
976
|
+
border: "none"
|
|
977
|
+
};
|
|
978
|
+
var dangerTitle = {
|
|
979
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
980
|
+
fontWeight: 600,
|
|
981
|
+
color: "var(--dauth-error, #ef4444)",
|
|
982
|
+
marginBottom: 4
|
|
983
|
+
};
|
|
984
|
+
var dangerDesc = {
|
|
985
|
+
fontSize: "var(--dauth-font-size-xs, 0.75rem)",
|
|
986
|
+
color: "var(--dauth-text-muted, #71717a)",
|
|
987
|
+
marginBottom: 12,
|
|
988
|
+
lineHeight: 1.5
|
|
989
|
+
};
|
|
990
|
+
var deleteBtn = {
|
|
991
|
+
padding: "8px 16px",
|
|
992
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
993
|
+
fontWeight: 500,
|
|
994
|
+
color: "var(--dauth-error, #ef4444)",
|
|
995
|
+
backgroundColor: "var(--dauth-error-bg, rgba(239, 68, 68, 0.1))",
|
|
996
|
+
border: "1px solid rgba(239, 68, 68, 0.2)",
|
|
997
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
998
|
+
cursor: "pointer",
|
|
999
|
+
transition: "background-color 150ms, border-color 150ms",
|
|
1000
|
+
fontFamily: "inherit"
|
|
1001
|
+
};
|
|
1002
|
+
var deletePanel = {
|
|
1003
|
+
marginTop: 12,
|
|
1004
|
+
padding: 16,
|
|
1005
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
1006
|
+
border: "1px solid rgba(239, 68, 68, 0.3)",
|
|
1007
|
+
backgroundColor: "var(--dauth-error-bg, rgba(239, 68, 68, 0.1))"
|
|
1008
|
+
};
|
|
1009
|
+
var deletePanelText = {
|
|
1010
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
1011
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
1012
|
+
marginBottom: 12,
|
|
1013
|
+
lineHeight: 1.5
|
|
1014
|
+
};
|
|
1015
|
+
var cancelBtn = {
|
|
1016
|
+
flex: 1,
|
|
1017
|
+
padding: "8px 16px",
|
|
1018
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
1019
|
+
fontWeight: 500,
|
|
1020
|
+
color: "var(--dauth-text-secondary, #a1a1aa)",
|
|
1021
|
+
backgroundColor: "transparent",
|
|
1022
|
+
border: "1px solid var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
1023
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
1024
|
+
cursor: "pointer",
|
|
1025
|
+
transition: "background-color 150ms",
|
|
1026
|
+
fontFamily: "inherit"
|
|
1027
|
+
};
|
|
1028
|
+
var deleteConfirmBtn = {
|
|
1029
|
+
flex: 1,
|
|
1030
|
+
padding: "8px 16px",
|
|
1031
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
1032
|
+
fontWeight: 500,
|
|
1033
|
+
color: "#ffffff",
|
|
1034
|
+
backgroundColor: "var(--dauth-error, #ef4444)",
|
|
1035
|
+
border: "none",
|
|
1036
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
1037
|
+
cursor: "pointer",
|
|
1038
|
+
transition: "opacity 150ms",
|
|
1039
|
+
fontFamily: "inherit",
|
|
1040
|
+
display: "flex",
|
|
1041
|
+
alignItems: "center",
|
|
1042
|
+
justifyContent: "center",
|
|
1043
|
+
gap: 8
|
|
1044
|
+
};
|
|
1045
|
+
var footerStyle = (isDesktop) => ({
|
|
1046
|
+
padding: "16px 24px",
|
|
1047
|
+
borderTop: "1px solid var(--dauth-border, rgba(255, 255, 255, 0.08))",
|
|
1048
|
+
flexShrink: 0,
|
|
1049
|
+
...!isDesktop ? {
|
|
1050
|
+
position: "sticky",
|
|
1051
|
+
bottom: 0,
|
|
1052
|
+
zIndex: 1,
|
|
1053
|
+
backgroundColor: "var(--dauth-surface, #1a1a2e)",
|
|
1054
|
+
paddingBottom: "max(16px, env(safe-area-inset-bottom))"
|
|
1055
|
+
} : {}
|
|
1056
|
+
});
|
|
1057
|
+
var saveBtn = {
|
|
1058
|
+
width: "100%",
|
|
1059
|
+
padding: "12px 24px",
|
|
1060
|
+
fontSize: "var(--dauth-font-size-base, 1rem)",
|
|
1061
|
+
fontWeight: 600,
|
|
1062
|
+
color: "#ffffff",
|
|
1063
|
+
backgroundColor: "var(--dauth-accent, #6366f1)",
|
|
1064
|
+
border: "none",
|
|
1065
|
+
borderRadius: "var(--dauth-radius-sm, 8px)",
|
|
1066
|
+
transition: "opacity 150ms, background-color 150ms",
|
|
1067
|
+
display: "flex",
|
|
1068
|
+
alignItems: "center",
|
|
1069
|
+
justifyContent: "center",
|
|
1070
|
+
gap: 8,
|
|
1071
|
+
fontFamily: "inherit"
|
|
1072
|
+
};
|
|
1073
|
+
var spinnerStyle = {
|
|
1074
|
+
display: "inline-block",
|
|
1075
|
+
width: 16,
|
|
1076
|
+
height: 16,
|
|
1077
|
+
border: "2px solid rgba(255, 255, 255, 0.3)",
|
|
1078
|
+
borderTopColor: "#ffffff",
|
|
1079
|
+
borderRadius: "50%",
|
|
1080
|
+
animation: "dauth-spin 0.6s linear infinite"
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// src/index.tsx
|
|
1084
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
362
1085
|
var defaultOnError = (error) => console.error(error);
|
|
363
1086
|
var DauthProvider = (props) => {
|
|
364
1087
|
const {
|
|
@@ -369,22 +1092,19 @@ var DauthProvider = (props) => {
|
|
|
369
1092
|
env,
|
|
370
1093
|
dauthUrl
|
|
371
1094
|
} = props;
|
|
372
|
-
const [dauthState, dispatch] = (0,
|
|
373
|
-
|
|
374
|
-
initialDauthState_default
|
|
375
|
-
);
|
|
376
|
-
(0, import_react.useEffect)(() => {
|
|
1095
|
+
const [dauthState, dispatch] = (0, import_react2.useReducer)(userReducer, initialDauthState_default);
|
|
1096
|
+
(0, import_react2.useEffect)(() => {
|
|
377
1097
|
setDauthUrl(dauthUrl);
|
|
378
1098
|
}, [dauthUrl]);
|
|
379
|
-
const handleError = (0,
|
|
1099
|
+
const handleError = (0, import_react2.useCallback)(
|
|
380
1100
|
(error) => (onError ?? defaultOnError)(error),
|
|
381
1101
|
[onError]
|
|
382
1102
|
);
|
|
383
|
-
const ctx = (0,
|
|
1103
|
+
const ctx = (0, import_react2.useMemo)(
|
|
384
1104
|
() => ({ dispatch, authProxyPath, onError: handleError }),
|
|
385
1105
|
[authProxyPath, handleError]
|
|
386
1106
|
);
|
|
387
|
-
(0,
|
|
1107
|
+
(0, import_react2.useEffect)(() => {
|
|
388
1108
|
const params = new URLSearchParams(window.location.search);
|
|
389
1109
|
const code = params.get(AUTH_CODE_PARAM);
|
|
390
1110
|
if (code) {
|
|
@@ -393,16 +1113,13 @@ var DauthProvider = (props) => {
|
|
|
393
1113
|
autoLoginAction(ctx);
|
|
394
1114
|
}
|
|
395
1115
|
}, []);
|
|
396
|
-
const loginWithRedirect = (0,
|
|
1116
|
+
const loginWithRedirect = (0, import_react2.useCallback)(() => {
|
|
397
1117
|
const base = `${getClientBasePath()}/${domainName}/${routes.signin}`;
|
|
398
1118
|
const url = env ? `${base}?env=${encodeURIComponent(env)}` : base;
|
|
399
1119
|
return window.location.replace(url);
|
|
400
1120
|
}, [domainName, env]);
|
|
401
|
-
const logout = (0,
|
|
402
|
-
|
|
403
|
-
[ctx]
|
|
404
|
-
);
|
|
405
|
-
const updateUser = (0, import_react.useCallback)(
|
|
1121
|
+
const logout = (0, import_react2.useCallback)(() => logoutAction(ctx), [ctx]);
|
|
1122
|
+
const updateUser = (0, import_react2.useCallback)(
|
|
406
1123
|
async (fields) => {
|
|
407
1124
|
const {
|
|
408
1125
|
name,
|
|
@@ -432,37 +1149,25 @@ var DauthProvider = (props) => {
|
|
|
432
1149
|
},
|
|
433
1150
|
[ctx]
|
|
434
1151
|
);
|
|
435
|
-
const
|
|
436
|
-
() => updateUserWithRedirectAction(ctx),
|
|
437
|
-
[ctx]
|
|
438
|
-
);
|
|
439
|
-
const deleteAccount = (0, import_react.useCallback)(
|
|
1152
|
+
const deleteAccount = (0, import_react2.useCallback)(
|
|
440
1153
|
() => deleteAccountAction(ctx),
|
|
441
1154
|
[ctx]
|
|
442
1155
|
);
|
|
443
|
-
const memoProvider = (0,
|
|
1156
|
+
const memoProvider = (0, import_react2.useMemo)(
|
|
444
1157
|
() => ({
|
|
445
1158
|
...dauthState,
|
|
446
1159
|
loginWithRedirect,
|
|
447
1160
|
logout,
|
|
448
1161
|
updateUser,
|
|
449
|
-
updateUserWithRedirect,
|
|
450
1162
|
deleteAccount
|
|
451
1163
|
}),
|
|
452
|
-
[
|
|
453
|
-
dauthState,
|
|
454
|
-
loginWithRedirect,
|
|
455
|
-
logout,
|
|
456
|
-
updateUser,
|
|
457
|
-
updateUserWithRedirect,
|
|
458
|
-
deleteAccount
|
|
459
|
-
]
|
|
1164
|
+
[dauthState, loginWithRedirect, logout, updateUser, deleteAccount]
|
|
460
1165
|
);
|
|
461
|
-
return /* @__PURE__ */ (0,
|
|
1166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DauthContext.Provider, { value: memoProvider, children });
|
|
462
1167
|
};
|
|
463
|
-
var DauthContext = (0,
|
|
1168
|
+
var DauthContext = (0, import_react2.createContext)(initialDauthState_default);
|
|
464
1169
|
var useDauth = () => {
|
|
465
|
-
const context = (0,
|
|
1170
|
+
const context = (0, import_react2.useContext)(DauthContext);
|
|
466
1171
|
if (!context) {
|
|
467
1172
|
throw new Error("useDauth must be used inside DauthProvider");
|
|
468
1173
|
}
|
|
@@ -470,6 +1175,7 @@ var useDauth = () => {
|
|
|
470
1175
|
};
|
|
471
1176
|
// Annotate the CommonJS export names for ESM import in node:
|
|
472
1177
|
0 && (module.exports = {
|
|
1178
|
+
DauthProfileModal,
|
|
473
1179
|
DauthProvider,
|
|
474
1180
|
useDauth
|
|
475
1181
|
});
|