@djangocfg/layouts 2.1.101 → 2.1.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/AIChatWidget-LUPM7S2O.mjs +1644 -0
  2. package/dist/AIChatWidget-LUPM7S2O.mjs.map +1 -0
  3. package/dist/AIChatWidget-O23TJJ7C.mjs +3 -0
  4. package/dist/AIChatWidget-O23TJJ7C.mjs.map +1 -0
  5. package/dist/chunk-53YKWR6F.mjs +6 -0
  6. package/dist/chunk-53YKWR6F.mjs.map +1 -0
  7. package/dist/chunk-EI7TDN2G.mjs +1652 -0
  8. package/dist/chunk-EI7TDN2G.mjs.map +1 -0
  9. package/dist/components.cjs +925 -0
  10. package/dist/components.cjs.map +1 -0
  11. package/dist/components.d.mts +583 -0
  12. package/dist/components.d.ts +583 -0
  13. package/dist/components.mjs +879 -0
  14. package/dist/components.mjs.map +1 -0
  15. package/dist/index.cjs +7573 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.mts +2376 -0
  18. package/dist/index.d.ts +2376 -0
  19. package/dist/index.mjs +5673 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/layouts.cjs +6530 -0
  22. package/dist/layouts.cjs.map +1 -0
  23. package/dist/layouts.d.mts +748 -0
  24. package/dist/layouts.d.ts +748 -0
  25. package/dist/layouts.mjs +4741 -0
  26. package/dist/layouts.mjs.map +1 -0
  27. package/dist/pages.cjs +178 -0
  28. package/dist/pages.cjs.map +1 -0
  29. package/dist/pages.d.mts +57 -0
  30. package/dist/pages.d.ts +57 -0
  31. package/dist/pages.mjs +168 -0
  32. package/dist/pages.mjs.map +1 -0
  33. package/dist/snippets.cjs +3793 -0
  34. package/dist/snippets.cjs.map +1 -0
  35. package/dist/snippets.d.mts +1192 -0
  36. package/dist/snippets.d.ts +1192 -0
  37. package/dist/snippets.mjs +3738 -0
  38. package/dist/snippets.mjs.map +1 -0
  39. package/dist/utils.cjs +34 -0
  40. package/dist/utils.cjs.map +1 -0
  41. package/dist/utils.d.mts +40 -0
  42. package/dist/utils.d.ts +40 -0
  43. package/dist/utils.mjs +25 -0
  44. package/dist/utils.mjs.map +1 -0
  45. package/package.json +38 -47
  46. package/src/components/errors/ErrorsTracker/components/ErrorButtons.tsx +2 -1
  47. package/src/layouts/ProfileLayout/ProfileLayout.tsx +507 -86
  48. package/src/layouts/ProfileLayout/components/DeleteAccountSection.tsx +2 -2
  49. package/src/snippets/AuthDialog/useAuthDialog.ts +1 -1
@@ -0,0 +1,925 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var components = require('@djangocfg/ui-nextjs/components');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var LucideIcons = require('lucide-react');
7
+ var lib = require('@djangocfg/ui-core/lib');
8
+ var auth = require('@djangocfg/api/auth');
9
+ var hooks = require('@djangocfg/ui-nextjs/hooks');
10
+ var hooks$1 = require('@djangocfg/ui-core/hooks');
11
+ var uiNextjs = require('@djangocfg/ui-nextjs');
12
+ var consola = require('consola');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ function _interopNamespace(e) {
17
+ if (e && e.__esModule) return e;
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
34
+ var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
35
+ var consola__default = /*#__PURE__*/_interopDefault(consola);
36
+
37
+ var __defProp = Object.defineProperty;
38
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
39
+ var defaultFallback = /* @__PURE__ */ jsxRuntime.jsx(
40
+ components.Preloader,
41
+ {
42
+ variant: "fullscreen",
43
+ text: "Loading...",
44
+ size: "lg",
45
+ backdrop: true,
46
+ backdropOpacity: 80
47
+ }
48
+ );
49
+ function ClientOnly({
50
+ children,
51
+ fallback = defaultFallback
52
+ }) {
53
+ const [mounted, setMounted] = react.useState(false);
54
+ react.useEffect(() => {
55
+ setMounted(true);
56
+ }, []);
57
+ if (!mounted) {
58
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
59
+ }
60
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
61
+ }
62
+ __name(ClientOnly, "ClientOnly");
63
+ function JsonLd({ data }) {
64
+ return /* @__PURE__ */ jsxRuntime.jsx(
65
+ "script",
66
+ {
67
+ type: "application/ld+json",
68
+ dangerouslySetInnerHTML: {
69
+ __html: JSON.stringify(data, null, 0)
70
+ }
71
+ }
72
+ );
73
+ }
74
+ __name(JsonLd, "JsonLd");
75
+ function getLucideIcon(icon, fallback = LucideIcons__namespace.CloudLightning) {
76
+ if (!icon) {
77
+ return fallback;
78
+ }
79
+ if (typeof icon === "string") {
80
+ const IconComponent = LucideIcons__namespace[icon];
81
+ return IconComponent || fallback;
82
+ }
83
+ return icon;
84
+ }
85
+ __name(getLucideIcon, "getLucideIcon");
86
+ function LucideIcon({
87
+ icon,
88
+ fallback = LucideIcons__namespace.CloudLightning,
89
+ className,
90
+ ...props
91
+ }) {
92
+ const IconComponent = getLucideIcon(icon, fallback);
93
+ return /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { className: lib.cn(className), ...props });
94
+ }
95
+ __name(LucideIcon, "LucideIcon");
96
+ var defaultFallback2 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
97
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]" }),
98
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: "Loading..." })
99
+ ] }) });
100
+ function Suspense({ children, fallback = defaultFallback2 }) {
101
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback, children });
102
+ }
103
+ __name(Suspense, "Suspense");
104
+ var _ErrorBoundary = class _ErrorBoundary extends react.Component {
105
+ constructor(props) {
106
+ super(props);
107
+ this.state = { hasError: false, error: null };
108
+ }
109
+ static getDerivedStateFromError(error) {
110
+ return { hasError: true, error };
111
+ }
112
+ componentDidCatch(error, errorInfo) {
113
+ if (this.props.onError) {
114
+ this.props.onError(error, errorInfo);
115
+ }
116
+ {
117
+ console.error("ErrorBoundary caught an error:", error, errorInfo);
118
+ }
119
+ }
120
+ render() {
121
+ if (this.state.hasError) {
122
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-md w-full space-y-4 text-center", children: [
123
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold text-foreground", children: "Something went wrong" }),
124
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "We're sorry, but something unexpected happened. Please try refreshing the page." }),
125
+ this.props.supportEmail && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
126
+ "If the problem persists, please contact",
127
+ " ",
128
+ /* @__PURE__ */ jsxRuntime.jsx(
129
+ "a",
130
+ {
131
+ href: `mailto:${this.props.supportEmail}`,
132
+ className: "text-primary hover:underline",
133
+ children: this.props.supportEmail
134
+ }
135
+ )
136
+ ] }),
137
+ /* @__PURE__ */ jsxRuntime.jsx(
138
+ "button",
139
+ {
140
+ onClick: () => window.location.reload(),
141
+ className: "px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90",
142
+ children: "Refresh Page"
143
+ }
144
+ )
145
+ ] }) });
146
+ }
147
+ return this.props.children;
148
+ }
149
+ };
150
+ __name(_ErrorBoundary, "ErrorBoundary");
151
+ var ErrorBoundary = _ErrorBoundary;
152
+
153
+ // src/components/errors/errorConfig.ts
154
+ function getErrorContent(statusCode) {
155
+ const code = typeof statusCode === "string" ? parseInt(statusCode, 10) : statusCode;
156
+ switch (code) {
157
+ // 400 Bad Request
158
+ case 400:
159
+ return {
160
+ title: "Bad Request",
161
+ description: "The request could not be understood. Please check your input and try again."
162
+ };
163
+ // 401 Unauthorized
164
+ case 401:
165
+ return {
166
+ title: "Authentication Required",
167
+ description: "You need to sign in to access this page."
168
+ };
169
+ // 403 Forbidden
170
+ case 403:
171
+ return {
172
+ title: "Access Denied",
173
+ description: "You don't have permission to access this resource."
174
+ };
175
+ // 404 Not Found
176
+ case 404:
177
+ return {
178
+ title: "Page Not Found",
179
+ description: "The page you're looking for doesn't exist or has been moved."
180
+ };
181
+ // 408 Request Timeout
182
+ case 408:
183
+ return {
184
+ title: "Request Timeout",
185
+ description: "The request took too long to process. Please try again."
186
+ };
187
+ // 500 Internal Server Error
188
+ case 500:
189
+ return {
190
+ title: "Server Error",
191
+ description: "Something went wrong on our end. We're working to fix it."
192
+ };
193
+ // 502 Bad Gateway
194
+ case 502:
195
+ return {
196
+ title: "Bad Gateway",
197
+ description: "The server received an invalid response. Please try again later."
198
+ };
199
+ // 503 Service Unavailable
200
+ case 503:
201
+ return {
202
+ title: "Service Unavailable",
203
+ description: "The service is temporarily unavailable. Please try again later."
204
+ };
205
+ // 504 Gateway Timeout
206
+ case 504:
207
+ return {
208
+ title: "Gateway Timeout",
209
+ description: "The server took too long to respond. Please try again."
210
+ };
211
+ // Default / Unknown Error
212
+ default:
213
+ return {
214
+ title: "Something Went Wrong",
215
+ description: "An unexpected error occurred. Please try again or contact support."
216
+ };
217
+ }
218
+ }
219
+ __name(getErrorContent, "getErrorContent");
220
+ var ERROR_CODES = {
221
+ BAD_REQUEST: 400,
222
+ UNAUTHORIZED: 401,
223
+ FORBIDDEN: 403,
224
+ NOT_FOUND: 404,
225
+ TIMEOUT: 408,
226
+ SERVER_ERROR: 500,
227
+ BAD_GATEWAY: 502,
228
+ SERVICE_UNAVAILABLE: 503,
229
+ GATEWAY_TIMEOUT: 504
230
+ };
231
+ function getErrorIcon(code) {
232
+ const c = code ? String(code) : "";
233
+ switch (c) {
234
+ case "404":
235
+ return /* @__PURE__ */ jsxRuntime.jsx(
236
+ "svg",
237
+ {
238
+ className: "w-32 h-32 mx-auto text-foreground/80",
239
+ viewBox: "0 0 32 32",
240
+ fill: "currentColor",
241
+ "aria-hidden": "true",
242
+ children: /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
243
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M19.889 21.734v-.947l-.631.947z" }),
244
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15.484 19.636h1.032a.017.017 0 0 1 .017.017v3.1a.016.016 0 0 1-.016.016h-1.034a.016.016 0 0 1-.016-.016v-3.1a.017.017 0 0 1 .017-.017z" }),
245
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { fillRule: "evenodd", children: [
246
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12.402 21.734v-.947l-.631.947z" }),
247
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 1.5A14.5 14.5 0 1 0 30.5 16 14.507 14.507 0 0 0 16 1.5zm-2.324 21.234H13.4v.532a.5.5 0 0 1-1 0v-.532h-1.563a.5.5 0 0 1-.416-.778l2.067-3.1a.5.5 0 0 1 .914.28v2.6h.274a.5.5 0 0 1 0 1zm-2.137-9.9A4.14 4.14 0 0 1 15.545 9.8a.5.5 0 0 1 0 1 3.138 3.138 0 0 0-3.04 2.3.5.5 0 0 1-.966-.259zm5.994 9.911a1.017 1.017 0 0 1-1.017 1.016h-1.032a1.017 1.017 0 0 1-1.017-1.016v-3.1a1.017 1.017 0 0 1 1.017-1.016h1.032a1.017 1.017 0 0 1 1.017 1.016zm3.63-.016h-.274v.532a.5.5 0 0 1-1 0v-.532h-1.565a.5.5 0 0 1-.416-.778l2.067-3.1a.5.5 0 0 1 .914.28v2.6h.274a.5.5 0 0 1 0 1zm1.036-1.52a.5.5 0 1 1-.4-.917 3.263 3.263 0 0 0-1.337-6.266.5.5 0 0 1-.5-.5 4.6 4.6 0 0 0-9.2 0 4.45 4.45 0 0 0 .153 1.161.5.5 0 0 1-.411.625 2.633 2.633 0 0 0-.364 5.148.5.5 0 0 1-.278.961 3.63 3.63 0 0 1-.024-6.984 5.467 5.467 0 0 1-.076-.911 5.6 5.6 0 0 1 11.182-.474 4.258 4.258 0 0 1 1.256 8.162z" })
248
+ ] })
249
+ ] })
250
+ }
251
+ );
252
+ case "500":
253
+ return /* @__PURE__ */ jsxRuntime.jsx(
254
+ "svg",
255
+ {
256
+ className: "w-32 h-32 mx-auto text-foreground/80",
257
+ viewBox: "0 0 512 512",
258
+ fill: "currentColor",
259
+ "aria-hidden": "true",
260
+ children: /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
261
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M256 118c-76.1 0-138 61.88-138 138s61.9 138.05 138 138.05 138-61.93 138-138S332.1 118 256 118zm0 237.93a30.12 30.12 0 1 1 30.11-30.12A30.15 30.15 0 0 1 256 355.88zm30.11-80.31a8.48 8.48 0 0 1-8.47 8.48h-43.28a8.48 8.48 0 0 1-8.47-8.48v-111a8.47 8.47 0 0 1 8.47-8.47h43.28a8.47 8.47 0 0 1 8.47 8.47z" }),
262
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M256 312.6a13.17 13.17 0 1 0 13.16 13.16A13.17 13.17 0 0 0 256 312.6zM242.84 173.07h26.32v94.02h-26.32z" }),
263
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M256 0C114.62 0 0 114.62 0 256s114.62 256 256 256 256-114.62 256-256S397.38 0 256 0zm109.57 365.6A155 155 0 1 1 411 256a153.91 153.91 0 0 1-45.43 109.6z" })
264
+ ] })
265
+ }
266
+ );
267
+ case "403":
268
+ return /* @__PURE__ */ jsxRuntime.jsx(
269
+ "svg",
270
+ {
271
+ className: "w-32 h-32 mx-auto text-foreground/80",
272
+ viewBox: "0 0 24 24",
273
+ fill: "currentColor",
274
+ "aria-hidden": "true",
275
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 1a11 11 0 1 0 11 11A11.013 11.013 0 0 0 12 1zm4.242 13.829a1 1 0 1 1-1.414 1.414L12 13.414l-2.828 2.829a1 1 0 0 1-1.414-1.414L10.586 12 7.758 9.171a1 1 0 1 1 1.414-1.414L12 10.586l2.828-2.829a1 1 0 1 1 1.414 1.414L13.414 12z" })
276
+ }
277
+ );
278
+ default:
279
+ return null;
280
+ }
281
+ }
282
+ __name(getErrorIcon, "getErrorIcon");
283
+ function ErrorLayout({
284
+ code,
285
+ title,
286
+ description,
287
+ actions,
288
+ showDefaultActions = true,
289
+ illustration,
290
+ supportEmail = "support@example.com"
291
+ }) {
292
+ const autoContent = code && (!title || !description) ? getErrorContent(code) : null;
293
+ const finalTitle = title || autoContent?.title || "Error";
294
+ const finalDescription = description || autoContent?.description;
295
+ const finalIllustration = illustration ?? getErrorIcon(code);
296
+ const handleGoBack = /* @__PURE__ */ __name(() => {
297
+ if (document.referrer && document.referrer !== window.location.href) {
298
+ window.location.href = document.referrer;
299
+ } else if (window.history.length > 1) {
300
+ window.history.back();
301
+ } else {
302
+ window.location.href = "/";
303
+ }
304
+ }, "handleGoBack");
305
+ const handleGoHome = /* @__PURE__ */ __name(() => {
306
+ window.location.href = "/";
307
+ }, "handleGoHome");
308
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-screen flex items-center justify-center px-4 bg-background", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-2xl w-full text-center space-y-8", children: [
309
+ finalIllustration && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-8", children: finalIllustration }),
310
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
311
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-4xl font-bold text-foreground", children: finalTitle }),
312
+ finalDescription && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground max-w-md mx-auto", children: finalDescription })
313
+ ] }),
314
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-center gap-4 pt-4", children: [
315
+ actions,
316
+ showDefaultActions && !actions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
317
+ /* @__PURE__ */ jsxRuntime.jsx(
318
+ components.Button,
319
+ {
320
+ variant: "outline",
321
+ size: "lg",
322
+ onClick: handleGoBack,
323
+ style: { minWidth: "140px", padding: "12px 32px" },
324
+ children: "Go Back"
325
+ }
326
+ ),
327
+ /* @__PURE__ */ jsxRuntime.jsx(
328
+ components.Button,
329
+ {
330
+ variant: "default",
331
+ size: "lg",
332
+ onClick: handleGoHome,
333
+ style: { minWidth: "140px", padding: "12px 32px" },
334
+ children: "Go Home"
335
+ }
336
+ )
337
+ ] })
338
+ ] }),
339
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-8 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
340
+ "Need help? Contact",
341
+ " ",
342
+ /* @__PURE__ */ jsxRuntime.jsx(
343
+ "a",
344
+ {
345
+ href: `mailto:${supportEmail}`,
346
+ className: "text-primary hover:underline",
347
+ children: "support"
348
+ }
349
+ )
350
+ ] }) })
351
+ ] }) });
352
+ }
353
+ __name(ErrorLayout, "ErrorLayout");
354
+ function RedirectPage({
355
+ authenticatedPath = "/private",
356
+ unauthenticatedPath = "/auth",
357
+ loadingText = "Loading..."
358
+ }) {
359
+ const { isAuthenticated } = auth.useAuth();
360
+ const router = hooks.useCfgRouter();
361
+ react.useEffect(() => {
362
+ if (!isAuthenticated) {
363
+ router.hardPush(unauthenticatedPath);
364
+ } else {
365
+ router.hardPush(authenticatedPath);
366
+ }
367
+ }, [isAuthenticated, router, authenticatedPath, unauthenticatedPath]);
368
+ return /* @__PURE__ */ jsxRuntime.jsx(
369
+ components.Preloader,
370
+ {
371
+ variant: "fullscreen",
372
+ text: loadingText,
373
+ size: "lg"
374
+ }
375
+ );
376
+ }
377
+ __name(RedirectPage, "RedirectPage");
378
+
379
+ // src/components/errors/ErrorsTracker/utils/formatters.ts
380
+ function formatZodIssues(error, maxIssues = 3) {
381
+ const issues = error.issues.slice(0, maxIssues);
382
+ const formatted = issues.map((issue) => {
383
+ const path = issue.path.join(".") || "root";
384
+ return `${path}: ${issue.message}`;
385
+ });
386
+ if (error.issues.length > maxIssues) {
387
+ formatted.push(`... and ${error.issues.length - maxIssues} more`);
388
+ }
389
+ return formatted.join(", ");
390
+ }
391
+ __name(formatZodIssues, "formatZodIssues");
392
+ function formatValidationErrorForClipboard(detail) {
393
+ const errorData = {
394
+ type: "validation",
395
+ timestamp: detail.timestamp.toISOString(),
396
+ operation: detail.operation,
397
+ endpoint: {
398
+ method: detail.method,
399
+ path: detail.path
400
+ },
401
+ validation_errors: detail.error.issues.map((issue) => ({
402
+ path: issue.path.join(".") || "root",
403
+ message: issue.message,
404
+ code: issue.code,
405
+ ..."expected" in issue && { expected: issue.expected },
406
+ ..."received" in issue && { received: issue.received },
407
+ ..."minimum" in issue && { minimum: issue.minimum },
408
+ ..."maximum" in issue && { maximum: issue.maximum }
409
+ })),
410
+ response: detail.response,
411
+ total_errors: detail.error.issues.length
412
+ };
413
+ return JSON.stringify(errorData, null, 2);
414
+ }
415
+ __name(formatValidationErrorForClipboard, "formatValidationErrorForClipboard");
416
+ function formatCORSErrorForClipboard(detail) {
417
+ const errorData = {
418
+ type: "cors",
419
+ timestamp: detail.timestamp.toISOString(),
420
+ url: detail.url,
421
+ method: detail.method,
422
+ error: detail.error
423
+ };
424
+ return JSON.stringify(errorData, null, 2);
425
+ }
426
+ __name(formatCORSErrorForClipboard, "formatCORSErrorForClipboard");
427
+ function formatNetworkErrorForClipboard(detail) {
428
+ const errorData = {
429
+ type: "network",
430
+ timestamp: detail.timestamp.toISOString(),
431
+ url: detail.url,
432
+ method: detail.method,
433
+ error: detail.error,
434
+ ...detail.statusCode && { statusCode: detail.statusCode }
435
+ };
436
+ return JSON.stringify(errorData, null, 2);
437
+ }
438
+ __name(formatNetworkErrorForClipboard, "formatNetworkErrorForClipboard");
439
+ function formatCentrifugoErrorForClipboard(detail) {
440
+ const errorData = {
441
+ type: "centrifugo",
442
+ timestamp: detail.timestamp.toISOString(),
443
+ method: detail.method,
444
+ error: detail.error,
445
+ ...detail.code !== void 0 && { code: detail.code },
446
+ ...detail.data && { data: detail.data }
447
+ };
448
+ return JSON.stringify(errorData, null, 2);
449
+ }
450
+ __name(formatCentrifugoErrorForClipboard, "formatCentrifugoErrorForClipboard");
451
+ function extractDomain(url) {
452
+ try {
453
+ const urlObj = new URL(url);
454
+ return urlObj.origin;
455
+ } catch {
456
+ return url;
457
+ }
458
+ }
459
+ __name(extractDomain, "extractDomain");
460
+ function formatErrorTitle(detail) {
461
+ switch (detail.type) {
462
+ case "validation":
463
+ return `\u274C Validation Error in ${detail.operation}`;
464
+ case "cors":
465
+ return "\u{1F6AB} CORS Error";
466
+ case "network":
467
+ return detail.statusCode ? `\u26A0\uFE0F Network Error (${detail.statusCode})` : "\u26A0\uFE0F Network Error";
468
+ case "centrifugo":
469
+ return detail.code !== void 0 ? `\u{1F50C} Centrifugo Error (${detail.code})` : "\u{1F50C} Centrifugo Error";
470
+ default:
471
+ return "\u274C Error";
472
+ }
473
+ }
474
+ __name(formatErrorTitle, "formatErrorTitle");
475
+ function getAuthToken() {
476
+ if (typeof window === "undefined") return null;
477
+ try {
478
+ const token = localStorage.getItem("access_token") || localStorage.getItem("token") || localStorage.getItem("auth_token");
479
+ return token;
480
+ } catch (error) {
481
+ consola__default.default.error("Failed to get auth token:", error);
482
+ return null;
483
+ }
484
+ }
485
+ __name(getAuthToken, "getAuthToken");
486
+ function formatHeaders(headers) {
487
+ return Object.entries(headers).map(
488
+ ([key, value]) => `-H '${key}: ${value}'`
489
+ );
490
+ }
491
+ __name(formatHeaders, "formatHeaders");
492
+ function escapeShell(str) {
493
+ return str.replace(/'/g, "'\\''");
494
+ }
495
+ __name(escapeShell, "escapeShell");
496
+ function generateCurl(options) {
497
+ const {
498
+ method,
499
+ path,
500
+ token = getAuthToken() || void 0,
501
+ // Auto-fetch if not provided
502
+ body,
503
+ headers = {},
504
+ baseUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"
505
+ } = options;
506
+ const curlParts = ["curl"];
507
+ const url = `${baseUrl}${path}`;
508
+ curlParts.push(`'${url}'`);
509
+ if (method.toUpperCase() !== "GET") {
510
+ curlParts.push(`-X ${method.toUpperCase()}`);
511
+ }
512
+ const allHeaders = {
513
+ "Accept": "*/*",
514
+ "Content-Type": "application/json",
515
+ ...headers
516
+ };
517
+ if (token) {
518
+ allHeaders["Authorization"] = `Bearer ${token}`;
519
+ }
520
+ const headerStrings = formatHeaders(allHeaders);
521
+ curlParts.push(...headerStrings);
522
+ if (body && method.toUpperCase() !== "GET") {
523
+ const bodyJson = typeof body === "string" ? body : JSON.stringify(body, null, 2);
524
+ curlParts.push(`-d '${escapeShell(bodyJson)}'`);
525
+ }
526
+ return curlParts.join(" \\\n ");
527
+ }
528
+ __name(generateCurl, "generateCurl");
529
+ function generateCurlFromError(detail) {
530
+ return generateCurl({
531
+ method: detail.method,
532
+ path: detail.path
533
+ // token is auto-fetched in generateCurl
534
+ });
535
+ }
536
+ __name(generateCurlFromError, "generateCurlFromError");
537
+ function formatErrorForClipboard(detail) {
538
+ switch (detail.type) {
539
+ case "validation":
540
+ return formatValidationErrorForClipboard(detail);
541
+ case "cors":
542
+ return formatCORSErrorForClipboard(detail);
543
+ case "network":
544
+ return formatNetworkErrorForClipboard(detail);
545
+ case "centrifugo":
546
+ return formatCentrifugoErrorForClipboard(detail);
547
+ default:
548
+ return JSON.stringify(detail, null, 2);
549
+ }
550
+ }
551
+ __name(formatErrorForClipboard, "formatErrorForClipboard");
552
+ function supportsCurl(detail) {
553
+ return detail.type === "validation";
554
+ }
555
+ __name(supportsCurl, "supportsCurl");
556
+ function ErrorButtons({ detail }) {
557
+ const { copyToClipboard } = hooks$1.useCopy();
558
+ const handleCopyError = /* @__PURE__ */ __name(async (e) => {
559
+ e.preventDefault();
560
+ e.stopPropagation();
561
+ const formattedError = formatErrorForClipboard(detail);
562
+ await copyToClipboard(formattedError, "\u2705 Error details copied");
563
+ }, "handleCopyError");
564
+ const handleCopyCurl = /* @__PURE__ */ __name(async (e) => {
565
+ e.preventDefault();
566
+ e.stopPropagation();
567
+ if (detail.type === "validation") {
568
+ const curl = generateCurlFromError({
569
+ method: detail.method,
570
+ path: detail.path,
571
+ response: detail.response
572
+ });
573
+ await copyToClipboard(curl, "\u2705 cURL command copied");
574
+ }
575
+ }, "handleCopyCurl");
576
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 mt-2", children: [
577
+ /* @__PURE__ */ jsxRuntime.jsxs(
578
+ uiNextjs.Button,
579
+ {
580
+ size: "sm",
581
+ variant: "secondary",
582
+ onClick: handleCopyError,
583
+ className: "h-8 text-xs bg-background hover:bg-background/80 text-foreground border border-border gap-1.5",
584
+ children: [
585
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Copy, { className: "h-3.5 w-3.5" }),
586
+ "Copy Error"
587
+ ]
588
+ }
589
+ ),
590
+ supportsCurl(detail) && /* @__PURE__ */ jsxRuntime.jsxs(
591
+ uiNextjs.Button,
592
+ {
593
+ size: "sm",
594
+ variant: "secondary",
595
+ onClick: handleCopyCurl,
596
+ className: "h-8 text-xs bg-background hover:bg-background/80 text-foreground border border-border gap-1.5",
597
+ children: [
598
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Terminal, { className: "h-3.5 w-3.5" }),
599
+ "Copy cURL"
600
+ ]
601
+ }
602
+ )
603
+ ] });
604
+ }
605
+ __name(ErrorButtons, "ErrorButtons");
606
+ function buildValidationDescription(detail, config) {
607
+ const descriptionParts = [];
608
+ if (config.showPath) {
609
+ descriptionParts.push(`${detail.method} ${detail.path}`);
610
+ }
611
+ if (config.showErrorCount) {
612
+ const count = detail.error.issues.length;
613
+ const plural = count === 1 ? "error" : "errors";
614
+ descriptionParts.push(`${count} ${plural}`);
615
+ }
616
+ const issuesText = formatZodIssues(detail.error, config.maxIssuesInToast);
617
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
618
+ descriptionParts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs opacity-90", children: descriptionParts.join(" \u2022 ") }),
619
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-90", children: issuesText }),
620
+ /* @__PURE__ */ jsxRuntime.jsx(ErrorButtons, { detail })
621
+ ] });
622
+ }
623
+ __name(buildValidationDescription, "buildValidationDescription");
624
+ function buildCORSDescription(detail, config) {
625
+ const domain = extractDomain(detail.url);
626
+ const parts = [];
627
+ if (config.showMethod && config.showUrl) {
628
+ parts.push(`${detail.method} ${detail.url}`);
629
+ } else if (config.showUrl) {
630
+ parts.push(detail.url);
631
+ } else if (config.showMethod) {
632
+ parts.push(`${detail.method} request blocked`);
633
+ }
634
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
635
+ parts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs opacity-90", children: parts.join(" \u2022 ") }),
636
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
637
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: "Request blocked by CORS policy" }),
638
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs opacity-75", children: [
639
+ "Check CORS configuration on ",
640
+ domain
641
+ ] })
642
+ ] }),
643
+ /* @__PURE__ */ jsxRuntime.jsx(ErrorButtons, { detail })
644
+ ] });
645
+ }
646
+ __name(buildCORSDescription, "buildCORSDescription");
647
+ function buildNetworkDescription(detail, config) {
648
+ const parts = [];
649
+ if (config.showMethod && config.showUrl) {
650
+ parts.push(`${detail.method} ${detail.url}`);
651
+ } else if (config.showUrl) {
652
+ parts.push(detail.url);
653
+ } else if (config.showMethod) {
654
+ parts.push(`${detail.method} request failed`);
655
+ }
656
+ if (config.showStatusCode && detail.statusCode) {
657
+ parts.push(`Status: ${detail.statusCode}`);
658
+ }
659
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
660
+ parts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs opacity-90", children: parts.join(" \u2022 ") }),
661
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-90", children: detail.error }),
662
+ /* @__PURE__ */ jsxRuntime.jsx(ErrorButtons, { detail })
663
+ ] });
664
+ }
665
+ __name(buildNetworkDescription, "buildNetworkDescription");
666
+ function buildCentrifugoDescription(detail, config) {
667
+ const parts = [];
668
+ if (config.showMethod) {
669
+ parts.push(`RPC: ${detail.method}`);
670
+ }
671
+ if (config.showCode && detail.code !== void 0) {
672
+ parts.push(`Code: ${detail.code}`);
673
+ }
674
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 text-sm", children: [
675
+ parts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-xs opacity-90", children: parts.join(" \u2022 ") }),
676
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "opacity-90", children: detail.error }),
677
+ /* @__PURE__ */ jsxRuntime.jsx(ErrorButtons, { detail })
678
+ ] });
679
+ }
680
+ __name(buildCentrifugoDescription, "buildCentrifugoDescription");
681
+ function createErrorToast(detail, config) {
682
+ let description;
683
+ if (detail.type === "validation") {
684
+ description = buildValidationDescription(detail, config);
685
+ } else if (detail.type === "cors") {
686
+ description = buildCORSDescription(detail, config);
687
+ } else if (detail.type === "centrifugo") {
688
+ description = buildCentrifugoDescription(detail, config);
689
+ } else {
690
+ description = buildNetworkDescription(detail, config);
691
+ }
692
+ return {
693
+ title: formatErrorTitle(detail),
694
+ description,
695
+ variant: "destructive",
696
+ duration: config.duration
697
+ };
698
+ }
699
+ __name(createErrorToast, "createErrorToast");
700
+
701
+ // src/components/errors/ErrorsTracker/types.ts
702
+ var ERROR_EVENTS = {
703
+ VALIDATION: "zod-validation-error",
704
+ CORS: "cors-error",
705
+ NETWORK: "network-error",
706
+ /** Unified Centrifugo event - filter by detail.type === 'error' */
707
+ CENTRIFUGO: "centrifugo"
708
+ };
709
+ var DEFAULT_ERROR_CONFIG = {
710
+ enabled: true,
711
+ showToast: true,
712
+ maxErrors: 50,
713
+ duration: 8e3
714
+ };
715
+ var DEFAULT_VALIDATION_CONFIG = {
716
+ ...DEFAULT_ERROR_CONFIG,
717
+ showOperation: true,
718
+ showPath: true,
719
+ showErrorCount: true,
720
+ maxIssuesInToast: 3
721
+ };
722
+ var DEFAULT_CORS_CONFIG = {
723
+ ...DEFAULT_ERROR_CONFIG,
724
+ duration: 0,
725
+ // Don't auto-dismiss CORS errors
726
+ showUrl: true,
727
+ showMethod: true
728
+ };
729
+ var DEFAULT_NETWORK_CONFIG = {
730
+ ...DEFAULT_ERROR_CONFIG,
731
+ duration: 0,
732
+ // Don't auto-dismiss network errors
733
+ showUrl: true,
734
+ showMethod: true,
735
+ showStatusCode: true
736
+ };
737
+ var DEFAULT_CENTRIFUGO_CONFIG = {
738
+ ...DEFAULT_ERROR_CONFIG,
739
+ duration: 0,
740
+ // Don't auto-dismiss centrifugo errors
741
+ showMethod: true,
742
+ showCode: true
743
+ };
744
+ var ErrorTrackingContext = react.createContext(void 0);
745
+ var errorIdCounter = 0;
746
+ function generateErrorId(type) {
747
+ return `${type}-error-${Date.now()}-${++errorIdCounter}`;
748
+ }
749
+ __name(generateErrorId, "generateErrorId");
750
+ function ErrorTrackingProvider({
751
+ children,
752
+ validation: userValidationConfig,
753
+ cors: userCorsConfig,
754
+ network: userNetworkConfig,
755
+ centrifugo: userCentrifugoConfig,
756
+ onError
757
+ }) {
758
+ const [errors, setErrors] = react.useState([]);
759
+ const validationConfig = {
760
+ ...DEFAULT_VALIDATION_CONFIG,
761
+ ...userValidationConfig
762
+ };
763
+ const corsConfig = {
764
+ ...DEFAULT_CORS_CONFIG,
765
+ ...userCorsConfig
766
+ };
767
+ const networkConfig = {
768
+ ...DEFAULT_NETWORK_CONFIG,
769
+ ...userNetworkConfig
770
+ };
771
+ const centrifugoConfig = {
772
+ ...DEFAULT_CENTRIFUGO_CONFIG,
773
+ ...userCentrifugoConfig
774
+ };
775
+ const clearErrors = react.useCallback(() => {
776
+ setErrors([]);
777
+ }, []);
778
+ const clearErrorsByType = react.useCallback((type) => {
779
+ setErrors((prev) => prev.filter((error) => error.type !== type));
780
+ }, []);
781
+ const clearError = react.useCallback((id) => {
782
+ setErrors((prev) => prev.filter((error) => error.id !== id));
783
+ }, []);
784
+ const handleError = react.useCallback(
785
+ (detail, config) => {
786
+ const storedError = {
787
+ ...detail,
788
+ id: generateErrorId(detail.type)
789
+ };
790
+ setErrors((prev) => {
791
+ const updated = [storedError, ...prev];
792
+ return updated.slice(0, config.maxErrors);
793
+ });
794
+ const shouldShowToast = onError?.(detail) !== false;
795
+ if (config.showToast && shouldShowToast) {
796
+ const toastOptions = createErrorToast(detail, config);
797
+ hooks$1.toast.error(toastOptions.title, {
798
+ description: toastOptions.description,
799
+ duration: toastOptions.duration
800
+ });
801
+ }
802
+ },
803
+ [onError]
804
+ );
805
+ react.useEffect(() => {
806
+ if (typeof window === "undefined") return;
807
+ const handlers = [];
808
+ if (validationConfig.enabled) {
809
+ const handler = /* @__PURE__ */ __name((event) => {
810
+ if (!(event instanceof CustomEvent)) return;
811
+ const detail = {
812
+ ...event.detail,
813
+ type: "validation"
814
+ };
815
+ handleError(detail, validationConfig);
816
+ }, "handler");
817
+ window.addEventListener(ERROR_EVENTS.VALIDATION, handler);
818
+ handlers.push({ event: ERROR_EVENTS.VALIDATION, handler });
819
+ }
820
+ if (corsConfig.enabled) {
821
+ const handler = /* @__PURE__ */ __name((event) => {
822
+ if (!(event instanceof CustomEvent)) return;
823
+ const detail = {
824
+ ...event.detail,
825
+ type: "cors"
826
+ };
827
+ handleError(detail, corsConfig);
828
+ }, "handler");
829
+ window.addEventListener(ERROR_EVENTS.CORS, handler);
830
+ handlers.push({ event: ERROR_EVENTS.CORS, handler });
831
+ }
832
+ if (networkConfig.enabled) {
833
+ const handler = /* @__PURE__ */ __name((event) => {
834
+ if (!(event instanceof CustomEvent)) return;
835
+ const detail = {
836
+ ...event.detail,
837
+ type: "network"
838
+ };
839
+ handleError(detail, networkConfig);
840
+ }, "handler");
841
+ window.addEventListener(ERROR_EVENTS.NETWORK, handler);
842
+ handlers.push({ event: ERROR_EVENTS.NETWORK, handler });
843
+ }
844
+ if (centrifugoConfig.enabled) {
845
+ const handler = /* @__PURE__ */ __name((event) => {
846
+ if (!(event instanceof CustomEvent)) return;
847
+ if (event.detail?.type !== "error") return;
848
+ const detail = {
849
+ type: "centrifugo",
850
+ method: event.detail.data?.method || "unknown",
851
+ error: event.detail.data?.error || "Unknown error",
852
+ code: event.detail.data?.code,
853
+ data: event.detail.data?.data,
854
+ timestamp: event.detail.timestamp || /* @__PURE__ */ new Date()
855
+ };
856
+ handleError(detail, centrifugoConfig);
857
+ }, "handler");
858
+ window.addEventListener(ERROR_EVENTS.CENTRIFUGO, handler);
859
+ handlers.push({ event: ERROR_EVENTS.CENTRIFUGO, handler });
860
+ }
861
+ return () => {
862
+ handlers.forEach(({ event, handler }) => {
863
+ window.removeEventListener(event, handler);
864
+ });
865
+ };
866
+ }, [handleError, validationConfig, corsConfig, networkConfig, centrifugoConfig]);
867
+ const validationErrors = errors.filter((e) => e.type === "validation");
868
+ const corsErrors = errors.filter((e) => e.type === "cors");
869
+ const networkErrors = errors.filter((e) => e.type === "network");
870
+ const centrifugoErrors = errors.filter((e) => e.type === "centrifugo");
871
+ const value = {
872
+ errors,
873
+ validationErrors,
874
+ corsErrors,
875
+ networkErrors,
876
+ centrifugoErrors,
877
+ clearErrors,
878
+ clearErrorsByType,
879
+ clearError,
880
+ errorCount: errors.length,
881
+ latestError: errors[0] || null,
882
+ config: {
883
+ validation: validationConfig,
884
+ cors: corsConfig,
885
+ network: networkConfig,
886
+ centrifugo: centrifugoConfig
887
+ }
888
+ };
889
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorTrackingContext.Provider, { value, children });
890
+ }
891
+ __name(ErrorTrackingProvider, "ErrorTrackingProvider");
892
+ function useErrors() {
893
+ const context = react.useContext(ErrorTrackingContext);
894
+ if (context === void 0) {
895
+ throw new Error("useErrors must be used within ErrorTrackingProvider");
896
+ }
897
+ return context;
898
+ }
899
+ __name(useErrors, "useErrors");
900
+
901
+ exports.ClientOnly = ClientOnly;
902
+ exports.ERROR_CODES = ERROR_CODES;
903
+ exports.ErrorBoundary = ErrorBoundary;
904
+ exports.ErrorButtons = ErrorButtons;
905
+ exports.ErrorLayout = ErrorLayout;
906
+ exports.ErrorTrackingProvider = ErrorTrackingProvider;
907
+ exports.JsonLd = JsonLd;
908
+ exports.LucideIcon = LucideIcon;
909
+ exports.RedirectPage = RedirectPage;
910
+ exports.Suspense = Suspense;
911
+ exports.createErrorToast = createErrorToast;
912
+ exports.extractDomain = extractDomain;
913
+ exports.formatCORSErrorForClipboard = formatCORSErrorForClipboard;
914
+ exports.formatCentrifugoErrorForClipboard = formatCentrifugoErrorForClipboard;
915
+ exports.formatErrorTitle = formatErrorTitle;
916
+ exports.formatNetworkErrorForClipboard = formatNetworkErrorForClipboard;
917
+ exports.formatValidationErrorForClipboard = formatValidationErrorForClipboard;
918
+ exports.formatZodIssues = formatZodIssues;
919
+ exports.generateCurl = generateCurl;
920
+ exports.generateCurlFromError = generateCurlFromError;
921
+ exports.getAuthToken = getAuthToken;
922
+ exports.getErrorContent = getErrorContent;
923
+ exports.useErrors = useErrors;
924
+ //# sourceMappingURL=components.cjs.map
925
+ //# sourceMappingURL=components.cjs.map