@djangocfg/ext-support 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/package.json +18 -12
- package/preview.png +0 -0
- package/src/config.ts +34 -13
- package/src/index.ts +2 -0
- package/dist/chunk-AZ4LWZB7.js +0 -2630
- package/dist/hooks.cjs +0 -2716
- package/dist/hooks.d.cts +0 -255
- package/dist/hooks.d.ts +0 -255
- package/dist/hooks.js +0 -1
- package/dist/index.cjs +0 -2693
- package/dist/index.d.cts +0 -1392
- package/dist/index.d.ts +0 -1392
- package/dist/index.js +0 -1
package/dist/index.cjs
DELETED
|
@@ -1,2693 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var consola = require('consola');
|
|
4
|
-
var pRetry = require('p-retry');
|
|
5
|
-
var zod = require('zod');
|
|
6
|
-
var api = require('@djangocfg/ext-base/api');
|
|
7
|
-
var React7 = require('react');
|
|
8
|
-
var useSWR = require('swr');
|
|
9
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
-
var auth = require('@djangocfg/api/auth');
|
|
11
|
-
var useSWRInfinite = require('swr/infinite');
|
|
12
|
-
var uiNextjs = require('@djangocfg/ui-nextjs');
|
|
13
|
-
var lucideReact = require('lucide-react');
|
|
14
|
-
var reactHookForm = require('react-hook-form');
|
|
15
|
-
var zod$1 = require('@hookform/resolvers/zod');
|
|
16
|
-
|
|
17
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
-
|
|
19
|
-
var pRetry__default = /*#__PURE__*/_interopDefault(pRetry);
|
|
20
|
-
var React7__default = /*#__PURE__*/_interopDefault(React7);
|
|
21
|
-
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
22
|
-
var useSWRInfinite__default = /*#__PURE__*/_interopDefault(useSWRInfinite);
|
|
23
|
-
|
|
24
|
-
var __defProp = Object.defineProperty;
|
|
25
|
-
var __export = (target, all) => {
|
|
26
|
-
for (var name in all)
|
|
27
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// src/api/generated/ext_support/ext_support__support/client.ts
|
|
31
|
-
var ExtSupportSupport = class {
|
|
32
|
-
client;
|
|
33
|
-
constructor(client) {
|
|
34
|
-
this.client = client;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
38
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
39
|
-
* their own.
|
|
40
|
-
*/
|
|
41
|
-
async ticketsList(...args) {
|
|
42
|
-
const isParamsObject = args.length === 1 && typeof args[0] === "object" && args[0] !== null && !Array.isArray(args[0]);
|
|
43
|
-
let params;
|
|
44
|
-
if (isParamsObject) {
|
|
45
|
-
params = args[0];
|
|
46
|
-
} else {
|
|
47
|
-
params = { page: args[0], page_size: args[1] };
|
|
48
|
-
}
|
|
49
|
-
const response = await this.client.request("GET", "/cfg/support/tickets/", { params });
|
|
50
|
-
return response;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
54
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
55
|
-
* their own.
|
|
56
|
-
*/
|
|
57
|
-
async ticketsCreate(data) {
|
|
58
|
-
const response = await this.client.request("POST", "/cfg/support/tickets/", { body: data });
|
|
59
|
-
return response;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
63
|
-
* or Session). Users can only access messages for their own tickets.
|
|
64
|
-
*/
|
|
65
|
-
async ticketsMessagesList(...args) {
|
|
66
|
-
const ticket_uuid = args[0];
|
|
67
|
-
const isParamsObject = args.length === 2 && typeof args[1] === "object" && args[1] !== null && !Array.isArray(args[1]);
|
|
68
|
-
let params;
|
|
69
|
-
if (isParamsObject) {
|
|
70
|
-
params = args[1];
|
|
71
|
-
} else {
|
|
72
|
-
params = { page: args[1], page_size: args[2] };
|
|
73
|
-
}
|
|
74
|
-
const response = await this.client.request("GET", `/cfg/support/tickets/${ticket_uuid}/messages/`, { params });
|
|
75
|
-
return response;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
79
|
-
* or Session). Users can only access messages for their own tickets.
|
|
80
|
-
*/
|
|
81
|
-
async ticketsMessagesCreate(ticket_uuid, data) {
|
|
82
|
-
const response = await this.client.request("POST", `/cfg/support/tickets/${ticket_uuid}/messages/`, { body: data });
|
|
83
|
-
return response;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
87
|
-
* or Session). Users can only access messages for their own tickets.
|
|
88
|
-
*/
|
|
89
|
-
async ticketsMessagesRetrieve(ticket_uuid, uuid) {
|
|
90
|
-
const response = await this.client.request("GET", `/cfg/support/tickets/${ticket_uuid}/messages/${uuid}/`);
|
|
91
|
-
return response;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
95
|
-
* or Session). Users can only access messages for their own tickets.
|
|
96
|
-
*/
|
|
97
|
-
async ticketsMessagesUpdate(ticket_uuid, uuid, data) {
|
|
98
|
-
const response = await this.client.request("PUT", `/cfg/support/tickets/${ticket_uuid}/messages/${uuid}/`, { body: data });
|
|
99
|
-
return response;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
103
|
-
* or Session). Users can only access messages for their own tickets.
|
|
104
|
-
*/
|
|
105
|
-
async ticketsMessagesPartialUpdate(ticket_uuid, uuid, data) {
|
|
106
|
-
const response = await this.client.request("PATCH", `/cfg/support/tickets/${ticket_uuid}/messages/${uuid}/`, { body: data });
|
|
107
|
-
return response;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* ViewSet for managing support messages. Requires authenticated user (JWT
|
|
111
|
-
* or Session). Users can only access messages for their own tickets.
|
|
112
|
-
*/
|
|
113
|
-
async ticketsMessagesDestroy(ticket_uuid, uuid) {
|
|
114
|
-
await this.client.request("DELETE", `/cfg/support/tickets/${ticket_uuid}/messages/${uuid}/`);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
119
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
120
|
-
* their own.
|
|
121
|
-
*/
|
|
122
|
-
async ticketsRetrieve(uuid) {
|
|
123
|
-
const response = await this.client.request("GET", `/cfg/support/tickets/${uuid}/`);
|
|
124
|
-
return response;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
128
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
129
|
-
* their own.
|
|
130
|
-
*/
|
|
131
|
-
async ticketsUpdate(uuid, data) {
|
|
132
|
-
const response = await this.client.request("PUT", `/cfg/support/tickets/${uuid}/`, { body: data });
|
|
133
|
-
return response;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
137
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
138
|
-
* their own.
|
|
139
|
-
*/
|
|
140
|
-
async ticketsPartialUpdate(uuid, data) {
|
|
141
|
-
const response = await this.client.request("PATCH", `/cfg/support/tickets/${uuid}/`, { body: data });
|
|
142
|
-
return response;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* ViewSet for managing support tickets. Requires authenticated user (JWT
|
|
146
|
-
* or Session). Staff users can see all tickets, regular users see only
|
|
147
|
-
* their own.
|
|
148
|
-
*/
|
|
149
|
-
async ticketsDestroy(uuid) {
|
|
150
|
-
await this.client.request("DELETE", `/cfg/support/tickets/${uuid}/`);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// src/api/generated/ext_support/ext_support__support/models.ts
|
|
156
|
-
var models_exports = {};
|
|
157
|
-
|
|
158
|
-
// src/api/generated/ext_support/http.ts
|
|
159
|
-
var FetchAdapter = class {
|
|
160
|
-
async request(request) {
|
|
161
|
-
const { method, url, headers, body, params, formData } = request;
|
|
162
|
-
let finalUrl = url;
|
|
163
|
-
if (params) {
|
|
164
|
-
const searchParams = new URLSearchParams();
|
|
165
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
166
|
-
if (value !== null && value !== void 0) {
|
|
167
|
-
searchParams.append(key, String(value));
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
const queryString = searchParams.toString();
|
|
171
|
-
if (queryString) {
|
|
172
|
-
finalUrl = url.includes("?") ? `${url}&${queryString}` : `${url}?${queryString}`;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
const finalHeaders = { ...headers };
|
|
176
|
-
let requestBody;
|
|
177
|
-
if (formData) {
|
|
178
|
-
requestBody = formData;
|
|
179
|
-
} else if (body) {
|
|
180
|
-
finalHeaders["Content-Type"] = "application/json";
|
|
181
|
-
requestBody = JSON.stringify(body);
|
|
182
|
-
}
|
|
183
|
-
const response = await fetch(finalUrl, {
|
|
184
|
-
method,
|
|
185
|
-
headers: finalHeaders,
|
|
186
|
-
body: requestBody,
|
|
187
|
-
credentials: "include"
|
|
188
|
-
// Include Django session cookies
|
|
189
|
-
});
|
|
190
|
-
let data = null;
|
|
191
|
-
const contentType = response.headers.get("content-type");
|
|
192
|
-
if (response.status !== 204 && contentType?.includes("application/json")) {
|
|
193
|
-
data = await response.json();
|
|
194
|
-
} else if (response.status !== 204) {
|
|
195
|
-
data = await response.text();
|
|
196
|
-
}
|
|
197
|
-
const responseHeaders = {};
|
|
198
|
-
response.headers.forEach((value, key) => {
|
|
199
|
-
responseHeaders[key] = value;
|
|
200
|
-
});
|
|
201
|
-
return {
|
|
202
|
-
data,
|
|
203
|
-
status: response.status,
|
|
204
|
-
statusText: response.statusText,
|
|
205
|
-
headers: responseHeaders
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// src/api/generated/ext_support/errors.ts
|
|
211
|
-
var APIError = class extends Error {
|
|
212
|
-
constructor(statusCode, statusText, response, url, message) {
|
|
213
|
-
super(message || `HTTP ${statusCode}: ${statusText}`);
|
|
214
|
-
this.statusCode = statusCode;
|
|
215
|
-
this.statusText = statusText;
|
|
216
|
-
this.response = response;
|
|
217
|
-
this.url = url;
|
|
218
|
-
this.name = "APIError";
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Get error details from response.
|
|
222
|
-
* DRF typically returns: { "detail": "Error message" } or { "field": ["error1", "error2"] }
|
|
223
|
-
*/
|
|
224
|
-
get details() {
|
|
225
|
-
if (typeof this.response === "object" && this.response !== null) {
|
|
226
|
-
return this.response;
|
|
227
|
-
}
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Get field-specific validation errors from DRF.
|
|
232
|
-
* Returns: { "field_name": ["error1", "error2"], ... }
|
|
233
|
-
*/
|
|
234
|
-
get fieldErrors() {
|
|
235
|
-
const details = this.details;
|
|
236
|
-
if (!details) return null;
|
|
237
|
-
const fieldErrors = {};
|
|
238
|
-
for (const [key, value] of Object.entries(details)) {
|
|
239
|
-
if (Array.isArray(value)) {
|
|
240
|
-
fieldErrors[key] = value;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return Object.keys(fieldErrors).length > 0 ? fieldErrors : null;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Get single error message from DRF.
|
|
247
|
-
* Checks for "detail", "message", or first field error.
|
|
248
|
-
*/
|
|
249
|
-
get errorMessage() {
|
|
250
|
-
const details = this.details;
|
|
251
|
-
if (!details) return this.message;
|
|
252
|
-
if (details.detail) {
|
|
253
|
-
return Array.isArray(details.detail) ? details.detail.join(", ") : String(details.detail);
|
|
254
|
-
}
|
|
255
|
-
if (details.message) {
|
|
256
|
-
return String(details.message);
|
|
257
|
-
}
|
|
258
|
-
const fieldErrors = this.fieldErrors;
|
|
259
|
-
if (fieldErrors) {
|
|
260
|
-
const firstField = Object.keys(fieldErrors)[0];
|
|
261
|
-
if (firstField) {
|
|
262
|
-
return `${firstField}: ${fieldErrors[firstField]?.join(", ")}`;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return this.message;
|
|
266
|
-
}
|
|
267
|
-
// Helper methods for common HTTP status codes
|
|
268
|
-
get isValidationError() {
|
|
269
|
-
return this.statusCode === 400;
|
|
270
|
-
}
|
|
271
|
-
get isAuthError() {
|
|
272
|
-
return this.statusCode === 401;
|
|
273
|
-
}
|
|
274
|
-
get isPermissionError() {
|
|
275
|
-
return this.statusCode === 403;
|
|
276
|
-
}
|
|
277
|
-
get isNotFoundError() {
|
|
278
|
-
return this.statusCode === 404;
|
|
279
|
-
}
|
|
280
|
-
get isServerError() {
|
|
281
|
-
return this.statusCode >= 500 && this.statusCode < 600;
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
var NetworkError = class extends Error {
|
|
285
|
-
constructor(message, url, originalError) {
|
|
286
|
-
super(message);
|
|
287
|
-
this.url = url;
|
|
288
|
-
this.originalError = originalError;
|
|
289
|
-
this.name = "NetworkError";
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
var DEFAULT_CONFIG = {
|
|
293
|
-
enabled: process.env.NODE_ENV !== "production",
|
|
294
|
-
logRequests: true,
|
|
295
|
-
logResponses: true,
|
|
296
|
-
logErrors: true,
|
|
297
|
-
logBodies: true,
|
|
298
|
-
logHeaders: false
|
|
299
|
-
};
|
|
300
|
-
var SENSITIVE_HEADERS = [
|
|
301
|
-
"authorization",
|
|
302
|
-
"cookie",
|
|
303
|
-
"set-cookie",
|
|
304
|
-
"x-api-key",
|
|
305
|
-
"x-csrf-token"
|
|
306
|
-
];
|
|
307
|
-
var APILogger = class {
|
|
308
|
-
config;
|
|
309
|
-
consola;
|
|
310
|
-
constructor(config = {}) {
|
|
311
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
312
|
-
this.consola = config.consola || consola.createConsola({
|
|
313
|
-
level: this.config.enabled ? 4 : 0
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Enable logging
|
|
318
|
-
*/
|
|
319
|
-
enable() {
|
|
320
|
-
this.config.enabled = true;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Disable logging
|
|
324
|
-
*/
|
|
325
|
-
disable() {
|
|
326
|
-
this.config.enabled = false;
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Update configuration
|
|
330
|
-
*/
|
|
331
|
-
setConfig(config) {
|
|
332
|
-
this.config = { ...this.config, ...config };
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Filter sensitive headers
|
|
336
|
-
*/
|
|
337
|
-
filterHeaders(headers) {
|
|
338
|
-
if (!headers) return {};
|
|
339
|
-
const filtered = {};
|
|
340
|
-
Object.keys(headers).forEach((key) => {
|
|
341
|
-
const lowerKey = key.toLowerCase();
|
|
342
|
-
if (SENSITIVE_HEADERS.includes(lowerKey)) {
|
|
343
|
-
filtered[key] = "***";
|
|
344
|
-
} else {
|
|
345
|
-
filtered[key] = headers[key] || "";
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
return filtered;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Log request
|
|
352
|
-
*/
|
|
353
|
-
logRequest(request) {
|
|
354
|
-
if (!this.config.enabled || !this.config.logRequests) return;
|
|
355
|
-
const { method, url, headers, body } = request;
|
|
356
|
-
this.consola.start(`${method} ${url}`);
|
|
357
|
-
if (this.config.logHeaders && headers) {
|
|
358
|
-
this.consola.debug("Headers:", this.filterHeaders(headers));
|
|
359
|
-
}
|
|
360
|
-
if (this.config.logBodies && body) {
|
|
361
|
-
this.consola.debug("Body:", body);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Log response
|
|
366
|
-
*/
|
|
367
|
-
logResponse(request, response) {
|
|
368
|
-
if (!this.config.enabled || !this.config.logResponses) return;
|
|
369
|
-
const { method, url } = request;
|
|
370
|
-
const { status, statusText, data, duration } = response;
|
|
371
|
-
this.consola.success(
|
|
372
|
-
`${method} ${url} ${status} ${statusText} (${duration}ms)`
|
|
373
|
-
);
|
|
374
|
-
if (this.config.logBodies && data) {
|
|
375
|
-
this.consola.debug("Response:", data);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Log error
|
|
380
|
-
*/
|
|
381
|
-
logError(request, error) {
|
|
382
|
-
if (!this.config.enabled || !this.config.logErrors) return;
|
|
383
|
-
const { method, url } = request;
|
|
384
|
-
const { message, statusCode, fieldErrors, duration } = error;
|
|
385
|
-
this.consola.error(
|
|
386
|
-
`${method} ${url} ${statusCode || "Network"} Error (${duration}ms)`
|
|
387
|
-
);
|
|
388
|
-
this.consola.error("Message:", message);
|
|
389
|
-
if (fieldErrors && Object.keys(fieldErrors).length > 0) {
|
|
390
|
-
this.consola.error("Field Errors:");
|
|
391
|
-
Object.entries(fieldErrors).forEach(([field, errors]) => {
|
|
392
|
-
errors.forEach((err) => {
|
|
393
|
-
this.consola.error(` \u2022 ${field}: ${err}`);
|
|
394
|
-
});
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Log general info
|
|
400
|
-
*/
|
|
401
|
-
info(message, ...args) {
|
|
402
|
-
if (!this.config.enabled) return;
|
|
403
|
-
this.consola.info(message, ...args);
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Log warning
|
|
407
|
-
*/
|
|
408
|
-
warn(message, ...args) {
|
|
409
|
-
if (!this.config.enabled) return;
|
|
410
|
-
this.consola.warn(message, ...args);
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Log error
|
|
414
|
-
*/
|
|
415
|
-
error(message, ...args) {
|
|
416
|
-
if (!this.config.enabled) return;
|
|
417
|
-
this.consola.error(message, ...args);
|
|
418
|
-
}
|
|
419
|
-
/**
|
|
420
|
-
* Log debug
|
|
421
|
-
*/
|
|
422
|
-
debug(message, ...args) {
|
|
423
|
-
if (!this.config.enabled) return;
|
|
424
|
-
this.consola.debug(message, ...args);
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Log success
|
|
428
|
-
*/
|
|
429
|
-
success(message, ...args) {
|
|
430
|
-
if (!this.config.enabled) return;
|
|
431
|
-
this.consola.success(message, ...args);
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Create a sub-logger with prefix
|
|
435
|
-
*/
|
|
436
|
-
withTag(tag) {
|
|
437
|
-
return this.consola.withTag(tag);
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
new APILogger();
|
|
441
|
-
var DEFAULT_RETRY_CONFIG = {
|
|
442
|
-
retries: 3,
|
|
443
|
-
factor: 2,
|
|
444
|
-
minTimeout: 1e3,
|
|
445
|
-
maxTimeout: 6e4,
|
|
446
|
-
randomize: true,
|
|
447
|
-
onFailedAttempt: () => {
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
function shouldRetry(error) {
|
|
451
|
-
if (error instanceof NetworkError) {
|
|
452
|
-
return true;
|
|
453
|
-
}
|
|
454
|
-
if (error instanceof APIError) {
|
|
455
|
-
const status = error.statusCode;
|
|
456
|
-
if (status >= 500 && status < 600) {
|
|
457
|
-
return true;
|
|
458
|
-
}
|
|
459
|
-
if (status === 429) {
|
|
460
|
-
return true;
|
|
461
|
-
}
|
|
462
|
-
return false;
|
|
463
|
-
}
|
|
464
|
-
return true;
|
|
465
|
-
}
|
|
466
|
-
async function withRetry(fn, config) {
|
|
467
|
-
const finalConfig = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
468
|
-
return pRetry__default.default(
|
|
469
|
-
async () => {
|
|
470
|
-
try {
|
|
471
|
-
return await fn();
|
|
472
|
-
} catch (error) {
|
|
473
|
-
if (!shouldRetry(error)) {
|
|
474
|
-
throw new pRetry.AbortError(error);
|
|
475
|
-
}
|
|
476
|
-
throw error;
|
|
477
|
-
}
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
retries: finalConfig.retries,
|
|
481
|
-
factor: finalConfig.factor,
|
|
482
|
-
minTimeout: finalConfig.minTimeout,
|
|
483
|
-
maxTimeout: finalConfig.maxTimeout,
|
|
484
|
-
randomize: finalConfig.randomize,
|
|
485
|
-
onFailedAttempt: finalConfig.onFailedAttempt ? (error) => {
|
|
486
|
-
const pRetryError = error;
|
|
487
|
-
finalConfig.onFailedAttempt({
|
|
488
|
-
error: pRetryError,
|
|
489
|
-
attemptNumber: pRetryError.attemptNumber,
|
|
490
|
-
retriesLeft: pRetryError.retriesLeft
|
|
491
|
-
});
|
|
492
|
-
} : void 0
|
|
493
|
-
}
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// src/api/generated/ext_support/client.ts
|
|
498
|
-
var APIClient = class {
|
|
499
|
-
baseUrl;
|
|
500
|
-
httpClient;
|
|
501
|
-
logger = null;
|
|
502
|
-
retryConfig = null;
|
|
503
|
-
// Sub-clients
|
|
504
|
-
ext_support_support;
|
|
505
|
-
constructor(baseUrl, options) {
|
|
506
|
-
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
507
|
-
this.httpClient = options?.httpClient || new FetchAdapter();
|
|
508
|
-
if (options?.loggerConfig !== void 0) {
|
|
509
|
-
this.logger = new APILogger(options.loggerConfig);
|
|
510
|
-
}
|
|
511
|
-
if (options?.retryConfig !== void 0) {
|
|
512
|
-
this.retryConfig = options.retryConfig;
|
|
513
|
-
}
|
|
514
|
-
this.ext_support_support = new ExtSupportSupport(this);
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* Get CSRF token from cookies (for SessionAuthentication).
|
|
518
|
-
*
|
|
519
|
-
* Returns null if cookie doesn't exist (JWT-only auth).
|
|
520
|
-
*/
|
|
521
|
-
getCsrfToken() {
|
|
522
|
-
const name = "csrftoken";
|
|
523
|
-
const value = `; ${document.cookie}`;
|
|
524
|
-
const parts = value.split(`; ${name}=`);
|
|
525
|
-
if (parts.length === 2) {
|
|
526
|
-
return parts.pop()?.split(";").shift() || null;
|
|
527
|
-
}
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Make HTTP request with Django CSRF and session handling.
|
|
532
|
-
* Automatically retries on network errors and 5xx server errors.
|
|
533
|
-
*/
|
|
534
|
-
async request(method, path, options) {
|
|
535
|
-
if (this.retryConfig) {
|
|
536
|
-
return withRetry(() => this._makeRequest(method, path, options), {
|
|
537
|
-
...this.retryConfig,
|
|
538
|
-
onFailedAttempt: (info) => {
|
|
539
|
-
if (this.logger) {
|
|
540
|
-
this.logger.warn(
|
|
541
|
-
`Retry attempt ${info.attemptNumber}/${info.retriesLeft + info.attemptNumber} for ${method} ${path}: ${info.error.message}`
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
this.retryConfig?.onFailedAttempt?.(info);
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
return this._makeRequest(method, path, options);
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Internal request method (without retry wrapper).
|
|
552
|
-
* Used by request() method with optional retry logic.
|
|
553
|
-
*/
|
|
554
|
-
async _makeRequest(method, path, options) {
|
|
555
|
-
const url = this.baseUrl ? `${this.baseUrl}${path}` : path;
|
|
556
|
-
const startTime = Date.now();
|
|
557
|
-
const headers = {
|
|
558
|
-
...options?.headers || {}
|
|
559
|
-
};
|
|
560
|
-
if (!options?.formData && !headers["Content-Type"]) {
|
|
561
|
-
headers["Content-Type"] = "application/json";
|
|
562
|
-
}
|
|
563
|
-
if (this.logger) {
|
|
564
|
-
this.logger.logRequest({
|
|
565
|
-
method,
|
|
566
|
-
url,
|
|
567
|
-
headers,
|
|
568
|
-
body: options?.formData || options?.body,
|
|
569
|
-
timestamp: startTime
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
try {
|
|
573
|
-
const response = await this.httpClient.request({
|
|
574
|
-
method,
|
|
575
|
-
url,
|
|
576
|
-
headers,
|
|
577
|
-
params: options?.params,
|
|
578
|
-
body: options?.body,
|
|
579
|
-
formData: options?.formData
|
|
580
|
-
});
|
|
581
|
-
const duration = Date.now() - startTime;
|
|
582
|
-
if (response.status >= 400) {
|
|
583
|
-
const error = new APIError(
|
|
584
|
-
response.status,
|
|
585
|
-
response.statusText,
|
|
586
|
-
response.data,
|
|
587
|
-
url
|
|
588
|
-
);
|
|
589
|
-
if (this.logger) {
|
|
590
|
-
this.logger.logError(
|
|
591
|
-
{
|
|
592
|
-
method,
|
|
593
|
-
url,
|
|
594
|
-
headers,
|
|
595
|
-
body: options?.formData || options?.body,
|
|
596
|
-
timestamp: startTime
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
message: error.message,
|
|
600
|
-
statusCode: response.status,
|
|
601
|
-
duration,
|
|
602
|
-
timestamp: Date.now()
|
|
603
|
-
}
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
throw error;
|
|
607
|
-
}
|
|
608
|
-
if (this.logger) {
|
|
609
|
-
this.logger.logResponse(
|
|
610
|
-
{
|
|
611
|
-
method,
|
|
612
|
-
url,
|
|
613
|
-
headers,
|
|
614
|
-
body: options?.formData || options?.body,
|
|
615
|
-
timestamp: startTime
|
|
616
|
-
},
|
|
617
|
-
{
|
|
618
|
-
status: response.status,
|
|
619
|
-
statusText: response.statusText,
|
|
620
|
-
data: response.data,
|
|
621
|
-
duration,
|
|
622
|
-
timestamp: Date.now()
|
|
623
|
-
}
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
return response.data;
|
|
627
|
-
} catch (error) {
|
|
628
|
-
const duration = Date.now() - startTime;
|
|
629
|
-
if (error instanceof APIError) {
|
|
630
|
-
throw error;
|
|
631
|
-
}
|
|
632
|
-
const isCORSError = error instanceof TypeError && (error.message.toLowerCase().includes("cors") || error.message.toLowerCase().includes("failed to fetch") || error.message.toLowerCase().includes("network request failed"));
|
|
633
|
-
if (this.logger) {
|
|
634
|
-
if (isCORSError) {
|
|
635
|
-
this.logger.error(`\u{1F6AB} CORS Error: ${method} ${url}`);
|
|
636
|
-
this.logger.error(` \u2192 ${error instanceof Error ? error.message : String(error)}`);
|
|
637
|
-
this.logger.error(` \u2192 Configure security_domains parameter on the server`);
|
|
638
|
-
} else {
|
|
639
|
-
this.logger.error(`\u26A0\uFE0F Network Error: ${method} ${url}`);
|
|
640
|
-
this.logger.error(` \u2192 ${error instanceof Error ? error.message : String(error)}`);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
if (typeof window !== "undefined") {
|
|
644
|
-
try {
|
|
645
|
-
if (isCORSError) {
|
|
646
|
-
window.dispatchEvent(new CustomEvent("cors-error", {
|
|
647
|
-
detail: {
|
|
648
|
-
url,
|
|
649
|
-
method,
|
|
650
|
-
error: error instanceof Error ? error.message : String(error),
|
|
651
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
652
|
-
},
|
|
653
|
-
bubbles: true,
|
|
654
|
-
cancelable: false
|
|
655
|
-
}));
|
|
656
|
-
} else {
|
|
657
|
-
window.dispatchEvent(new CustomEvent("network-error", {
|
|
658
|
-
detail: {
|
|
659
|
-
url,
|
|
660
|
-
method,
|
|
661
|
-
error: error instanceof Error ? error.message : String(error),
|
|
662
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
663
|
-
},
|
|
664
|
-
bubbles: true,
|
|
665
|
-
cancelable: false
|
|
666
|
-
}));
|
|
667
|
-
}
|
|
668
|
-
} catch (eventError) {
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
const networkError = error instanceof Error ? new NetworkError(error.message, url, error) : new NetworkError("Unknown error", url);
|
|
672
|
-
if (this.logger) {
|
|
673
|
-
this.logger.logError(
|
|
674
|
-
{
|
|
675
|
-
method,
|
|
676
|
-
url,
|
|
677
|
-
headers,
|
|
678
|
-
body: options?.formData || options?.body,
|
|
679
|
-
timestamp: startTime
|
|
680
|
-
},
|
|
681
|
-
{
|
|
682
|
-
message: networkError.message,
|
|
683
|
-
duration,
|
|
684
|
-
timestamp: Date.now()
|
|
685
|
-
}
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
throw networkError;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
// src/api/generated/ext_support/storage.ts
|
|
694
|
-
var LocalStorageAdapter = class {
|
|
695
|
-
logger;
|
|
696
|
-
constructor(logger2) {
|
|
697
|
-
this.logger = logger2;
|
|
698
|
-
}
|
|
699
|
-
getItem(key) {
|
|
700
|
-
try {
|
|
701
|
-
if (typeof window !== "undefined" && window.localStorage) {
|
|
702
|
-
const value = localStorage.getItem(key);
|
|
703
|
-
this.logger?.debug(`LocalStorage.getItem("${key}"): ${value ? "found" : "not found"}`);
|
|
704
|
-
return value;
|
|
705
|
-
}
|
|
706
|
-
this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
|
|
707
|
-
} catch (error) {
|
|
708
|
-
this.logger?.error("LocalStorage.getItem failed:", error);
|
|
709
|
-
}
|
|
710
|
-
return null;
|
|
711
|
-
}
|
|
712
|
-
setItem(key, value) {
|
|
713
|
-
try {
|
|
714
|
-
if (typeof window !== "undefined" && window.localStorage) {
|
|
715
|
-
localStorage.setItem(key, value);
|
|
716
|
-
this.logger?.debug(`LocalStorage.setItem("${key}"): success`);
|
|
717
|
-
} else {
|
|
718
|
-
this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
|
|
719
|
-
}
|
|
720
|
-
} catch (error) {
|
|
721
|
-
this.logger?.error("LocalStorage.setItem failed:", error);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
removeItem(key) {
|
|
725
|
-
try {
|
|
726
|
-
if (typeof window !== "undefined" && window.localStorage) {
|
|
727
|
-
localStorage.removeItem(key);
|
|
728
|
-
this.logger?.debug(`LocalStorage.removeItem("${key}"): success`);
|
|
729
|
-
} else {
|
|
730
|
-
this.logger?.warn("LocalStorage not available: window.localStorage is undefined");
|
|
731
|
-
}
|
|
732
|
-
} catch (error) {
|
|
733
|
-
this.logger?.error("LocalStorage.removeItem failed:", error);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
};
|
|
737
|
-
var CookieStorageAdapter = class {
|
|
738
|
-
logger;
|
|
739
|
-
constructor(logger2) {
|
|
740
|
-
this.logger = logger2;
|
|
741
|
-
}
|
|
742
|
-
getItem(key) {
|
|
743
|
-
try {
|
|
744
|
-
if (typeof document === "undefined") {
|
|
745
|
-
this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
|
|
746
|
-
return null;
|
|
747
|
-
}
|
|
748
|
-
const value = `; ${document.cookie}`;
|
|
749
|
-
const parts = value.split(`; ${key}=`);
|
|
750
|
-
if (parts.length === 2) {
|
|
751
|
-
const result = parts.pop()?.split(";").shift() || null;
|
|
752
|
-
this.logger?.debug(`CookieStorage.getItem("${key}"): ${result ? "found" : "not found"}`);
|
|
753
|
-
return result;
|
|
754
|
-
}
|
|
755
|
-
this.logger?.debug(`CookieStorage.getItem("${key}"): not found`);
|
|
756
|
-
} catch (error) {
|
|
757
|
-
this.logger?.error("CookieStorage.getItem failed:", error);
|
|
758
|
-
}
|
|
759
|
-
return null;
|
|
760
|
-
}
|
|
761
|
-
setItem(key, value) {
|
|
762
|
-
try {
|
|
763
|
-
if (typeof document !== "undefined") {
|
|
764
|
-
document.cookie = `${key}=${value}; path=/; max-age=31536000`;
|
|
765
|
-
this.logger?.debug(`CookieStorage.setItem("${key}"): success`);
|
|
766
|
-
} else {
|
|
767
|
-
this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
|
|
768
|
-
}
|
|
769
|
-
} catch (error) {
|
|
770
|
-
this.logger?.error("CookieStorage.setItem failed:", error);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
removeItem(key) {
|
|
774
|
-
try {
|
|
775
|
-
if (typeof document !== "undefined") {
|
|
776
|
-
document.cookie = `${key}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
777
|
-
this.logger?.debug(`CookieStorage.removeItem("${key}"): success`);
|
|
778
|
-
} else {
|
|
779
|
-
this.logger?.warn("Cookies not available: document is undefined (SSR context?)");
|
|
780
|
-
}
|
|
781
|
-
} catch (error) {
|
|
782
|
-
this.logger?.error("CookieStorage.removeItem failed:", error);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
};
|
|
786
|
-
var MemoryStorageAdapter = class {
|
|
787
|
-
storage = /* @__PURE__ */ new Map();
|
|
788
|
-
logger;
|
|
789
|
-
constructor(logger2) {
|
|
790
|
-
this.logger = logger2;
|
|
791
|
-
}
|
|
792
|
-
getItem(key) {
|
|
793
|
-
const value = this.storage.get(key) || null;
|
|
794
|
-
this.logger?.debug(`MemoryStorage.getItem("${key}"): ${value ? "found" : "not found"}`);
|
|
795
|
-
return value;
|
|
796
|
-
}
|
|
797
|
-
setItem(key, value) {
|
|
798
|
-
this.storage.set(key, value);
|
|
799
|
-
this.logger?.debug(`MemoryStorage.setItem("${key}"): success`);
|
|
800
|
-
}
|
|
801
|
-
removeItem(key) {
|
|
802
|
-
this.storage.delete(key);
|
|
803
|
-
this.logger?.debug(`MemoryStorage.removeItem("${key}"): success`);
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
|
|
807
|
-
// src/api/generated/ext_support/enums.ts
|
|
808
|
-
var enums_exports = {};
|
|
809
|
-
__export(enums_exports, {
|
|
810
|
-
PatchedTicketRequestStatus: () => PatchedTicketRequestStatus,
|
|
811
|
-
TicketRequestStatus: () => TicketRequestStatus,
|
|
812
|
-
TicketStatus: () => TicketStatus
|
|
813
|
-
});
|
|
814
|
-
var PatchedTicketRequestStatus = /* @__PURE__ */ ((PatchedTicketRequestStatus2) => {
|
|
815
|
-
PatchedTicketRequestStatus2["OPEN"] = "open";
|
|
816
|
-
PatchedTicketRequestStatus2["WAITING_FOR_USER"] = "waiting_for_user";
|
|
817
|
-
PatchedTicketRequestStatus2["WAITING_FOR_ADMIN"] = "waiting_for_admin";
|
|
818
|
-
PatchedTicketRequestStatus2["RESOLVED"] = "resolved";
|
|
819
|
-
PatchedTicketRequestStatus2["CLOSED"] = "closed";
|
|
820
|
-
return PatchedTicketRequestStatus2;
|
|
821
|
-
})(PatchedTicketRequestStatus || {});
|
|
822
|
-
var TicketStatus = /* @__PURE__ */ ((TicketStatus2) => {
|
|
823
|
-
TicketStatus2["OPEN"] = "open";
|
|
824
|
-
TicketStatus2["WAITING_FOR_USER"] = "waiting_for_user";
|
|
825
|
-
TicketStatus2["WAITING_FOR_ADMIN"] = "waiting_for_admin";
|
|
826
|
-
TicketStatus2["RESOLVED"] = "resolved";
|
|
827
|
-
TicketStatus2["CLOSED"] = "closed";
|
|
828
|
-
return TicketStatus2;
|
|
829
|
-
})(TicketStatus || {});
|
|
830
|
-
var TicketRequestStatus = /* @__PURE__ */ ((TicketRequestStatus2) => {
|
|
831
|
-
TicketRequestStatus2["OPEN"] = "open";
|
|
832
|
-
TicketRequestStatus2["WAITING_FOR_USER"] = "waiting_for_user";
|
|
833
|
-
TicketRequestStatus2["WAITING_FOR_ADMIN"] = "waiting_for_admin";
|
|
834
|
-
TicketRequestStatus2["RESOLVED"] = "resolved";
|
|
835
|
-
TicketRequestStatus2["CLOSED"] = "closed";
|
|
836
|
-
return TicketRequestStatus2;
|
|
837
|
-
})(TicketRequestStatus || {});
|
|
838
|
-
|
|
839
|
-
// src/api/generated/ext_support/_utils/schemas/index.ts
|
|
840
|
-
var schemas_exports = {};
|
|
841
|
-
__export(schemas_exports, {
|
|
842
|
-
MessageCreateRequestSchema: () => MessageCreateRequestSchema,
|
|
843
|
-
MessageCreateSchema: () => MessageCreateSchema,
|
|
844
|
-
MessageRequestSchema: () => MessageRequestSchema,
|
|
845
|
-
MessageSchema: () => MessageSchema,
|
|
846
|
-
PaginatedMessageListSchema: () => PaginatedMessageListSchema,
|
|
847
|
-
PaginatedTicketListSchema: () => PaginatedTicketListSchema,
|
|
848
|
-
PatchedMessageRequestSchema: () => PatchedMessageRequestSchema,
|
|
849
|
-
PatchedTicketRequestSchema: () => PatchedTicketRequestSchema,
|
|
850
|
-
SenderSchema: () => SenderSchema,
|
|
851
|
-
TicketRequestSchema: () => TicketRequestSchema,
|
|
852
|
-
TicketSchema: () => TicketSchema
|
|
853
|
-
});
|
|
854
|
-
var SenderSchema = zod.z.object({
|
|
855
|
-
id: zod.z.int(),
|
|
856
|
-
display_username: zod.z.string(),
|
|
857
|
-
email: zod.z.email(),
|
|
858
|
-
avatar: zod.z.string().nullable(),
|
|
859
|
-
initials: zod.z.string(),
|
|
860
|
-
is_staff: zod.z.boolean(),
|
|
861
|
-
is_superuser: zod.z.boolean()
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
// src/api/generated/ext_support/_utils/schemas/Message.schema.ts
|
|
865
|
-
var MessageSchema = zod.z.object({
|
|
866
|
-
uuid: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
867
|
-
ticket: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
868
|
-
sender: SenderSchema,
|
|
869
|
-
is_from_author: zod.z.boolean(),
|
|
870
|
-
text: zod.z.string(),
|
|
871
|
-
created_at: zod.z.iso.datetime()
|
|
872
|
-
});
|
|
873
|
-
var MessageCreateSchema = zod.z.object({
|
|
874
|
-
text: zod.z.string()
|
|
875
|
-
});
|
|
876
|
-
var MessageCreateRequestSchema = zod.z.object({
|
|
877
|
-
text: zod.z.string().min(1)
|
|
878
|
-
});
|
|
879
|
-
var MessageRequestSchema = zod.z.object({
|
|
880
|
-
text: zod.z.string().min(1)
|
|
881
|
-
});
|
|
882
|
-
var PaginatedMessageListSchema = zod.z.object({
|
|
883
|
-
count: zod.z.int(),
|
|
884
|
-
page: zod.z.int(),
|
|
885
|
-
pages: zod.z.int(),
|
|
886
|
-
page_size: zod.z.int(),
|
|
887
|
-
has_next: zod.z.boolean(),
|
|
888
|
-
has_previous: zod.z.boolean(),
|
|
889
|
-
next_page: zod.z.int().nullable().optional(),
|
|
890
|
-
previous_page: zod.z.int().nullable().optional(),
|
|
891
|
-
results: zod.z.array(MessageSchema)
|
|
892
|
-
});
|
|
893
|
-
var TicketSchema = zod.z.object({
|
|
894
|
-
uuid: zod.z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
895
|
-
user: zod.z.int(),
|
|
896
|
-
subject: zod.z.string().max(255),
|
|
897
|
-
status: zod.z.nativeEnum(TicketStatus).optional(),
|
|
898
|
-
created_at: zod.z.iso.datetime(),
|
|
899
|
-
unanswered_messages_count: zod.z.int()
|
|
900
|
-
});
|
|
901
|
-
|
|
902
|
-
// src/api/generated/ext_support/_utils/schemas/PaginatedTicketList.schema.ts
|
|
903
|
-
var PaginatedTicketListSchema = zod.z.object({
|
|
904
|
-
count: zod.z.int(),
|
|
905
|
-
page: zod.z.int(),
|
|
906
|
-
pages: zod.z.int(),
|
|
907
|
-
page_size: zod.z.int(),
|
|
908
|
-
has_next: zod.z.boolean(),
|
|
909
|
-
has_previous: zod.z.boolean(),
|
|
910
|
-
next_page: zod.z.int().nullable().optional(),
|
|
911
|
-
previous_page: zod.z.int().nullable().optional(),
|
|
912
|
-
results: zod.z.array(TicketSchema)
|
|
913
|
-
});
|
|
914
|
-
var PatchedMessageRequestSchema = zod.z.object({
|
|
915
|
-
text: zod.z.string().min(1).optional()
|
|
916
|
-
});
|
|
917
|
-
var PatchedTicketRequestSchema = zod.z.object({
|
|
918
|
-
user: zod.z.int().optional(),
|
|
919
|
-
subject: zod.z.string().min(1).max(255).optional(),
|
|
920
|
-
status: zod.z.nativeEnum(PatchedTicketRequestStatus).optional()
|
|
921
|
-
});
|
|
922
|
-
var TicketRequestSchema = zod.z.object({
|
|
923
|
-
user: zod.z.int(),
|
|
924
|
-
subject: zod.z.string().min(1).max(255),
|
|
925
|
-
status: zod.z.nativeEnum(TicketRequestStatus).optional()
|
|
926
|
-
});
|
|
927
|
-
|
|
928
|
-
// src/api/generated/ext_support/validation-events.ts
|
|
929
|
-
function dispatchValidationError(detail) {
|
|
930
|
-
if (typeof window === "undefined") {
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
try {
|
|
934
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
935
|
-
detail,
|
|
936
|
-
bubbles: true,
|
|
937
|
-
cancelable: false
|
|
938
|
-
});
|
|
939
|
-
window.dispatchEvent(event);
|
|
940
|
-
} catch (error) {
|
|
941
|
-
console.warn("Failed to dispatch validation error event:", error);
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
function onValidationError(callback) {
|
|
945
|
-
if (typeof window === "undefined") {
|
|
946
|
-
return () => {
|
|
947
|
-
};
|
|
948
|
-
}
|
|
949
|
-
const handler = (event) => {
|
|
950
|
-
if (event instanceof CustomEvent) {
|
|
951
|
-
callback(event.detail);
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
window.addEventListener("zod-validation-error", handler);
|
|
955
|
-
return () => {
|
|
956
|
-
window.removeEventListener("zod-validation-error", handler);
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
function formatZodError(error) {
|
|
960
|
-
const issues = error.issues.map((issue, index) => {
|
|
961
|
-
const path = issue.path.join(".") || "root";
|
|
962
|
-
const parts = [`${index + 1}. ${path}: ${issue.message}`];
|
|
963
|
-
if ("expected" in issue && issue.expected) {
|
|
964
|
-
parts.push(` Expected: ${issue.expected}`);
|
|
965
|
-
}
|
|
966
|
-
if ("received" in issue && issue.received) {
|
|
967
|
-
parts.push(` Received: ${issue.received}`);
|
|
968
|
-
}
|
|
969
|
-
return parts.join("\n");
|
|
970
|
-
});
|
|
971
|
-
return issues.join("\n");
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
// src/api/generated/ext_support/_utils/fetchers/index.ts
|
|
975
|
-
var fetchers_exports = {};
|
|
976
|
-
__export(fetchers_exports, {
|
|
977
|
-
createSupportTicketsCreate: () => createSupportTicketsCreate,
|
|
978
|
-
createSupportTicketsMessagesCreate: () => createSupportTicketsMessagesCreate,
|
|
979
|
-
deleteSupportTicketsDestroy: () => deleteSupportTicketsDestroy,
|
|
980
|
-
deleteSupportTicketsMessagesDestroy: () => deleteSupportTicketsMessagesDestroy,
|
|
981
|
-
getSupportTicketsList: () => getSupportTicketsList,
|
|
982
|
-
getSupportTicketsMessagesList: () => getSupportTicketsMessagesList,
|
|
983
|
-
getSupportTicketsMessagesRetrieve: () => getSupportTicketsMessagesRetrieve,
|
|
984
|
-
getSupportTicketsRetrieve: () => getSupportTicketsRetrieve,
|
|
985
|
-
partialUpdateSupportTicketsMessagesPartialUpdate: () => partialUpdateSupportTicketsMessagesPartialUpdate,
|
|
986
|
-
partialUpdateSupportTicketsPartialUpdate: () => partialUpdateSupportTicketsPartialUpdate,
|
|
987
|
-
updateSupportTicketsMessagesUpdate: () => updateSupportTicketsMessagesUpdate,
|
|
988
|
-
updateSupportTicketsUpdate: () => updateSupportTicketsUpdate
|
|
989
|
-
});
|
|
990
|
-
|
|
991
|
-
// src/api/generated/ext_support/api-instance.ts
|
|
992
|
-
var globalAPI = null;
|
|
993
|
-
function getAPIInstance() {
|
|
994
|
-
if (!globalAPI) {
|
|
995
|
-
throw new Error(
|
|
996
|
-
'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })'
|
|
997
|
-
);
|
|
998
|
-
}
|
|
999
|
-
return globalAPI;
|
|
1000
|
-
}
|
|
1001
|
-
function isAPIConfigured() {
|
|
1002
|
-
return globalAPI !== null;
|
|
1003
|
-
}
|
|
1004
|
-
function configureAPI(config) {
|
|
1005
|
-
globalAPI = new API(config.baseUrl, config.options);
|
|
1006
|
-
if (config.token) {
|
|
1007
|
-
globalAPI.setToken(config.token, config.refreshToken);
|
|
1008
|
-
}
|
|
1009
|
-
return globalAPI;
|
|
1010
|
-
}
|
|
1011
|
-
function reconfigureAPI(updates) {
|
|
1012
|
-
const instance = getAPIInstance();
|
|
1013
|
-
if (updates.baseUrl) {
|
|
1014
|
-
instance.setBaseUrl(updates.baseUrl);
|
|
1015
|
-
}
|
|
1016
|
-
if (updates.token) {
|
|
1017
|
-
instance.setToken(updates.token, updates.refreshToken);
|
|
1018
|
-
}
|
|
1019
|
-
return instance;
|
|
1020
|
-
}
|
|
1021
|
-
function clearAPITokens() {
|
|
1022
|
-
const instance = getAPIInstance();
|
|
1023
|
-
instance.clearTokens();
|
|
1024
|
-
}
|
|
1025
|
-
function resetAPI() {
|
|
1026
|
-
if (globalAPI) {
|
|
1027
|
-
globalAPI.clearTokens();
|
|
1028
|
-
}
|
|
1029
|
-
globalAPI = null;
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
// src/api/generated/ext_support/_utils/fetchers/ext_support__support.ts
|
|
1033
|
-
async function getSupportTicketsList(params, client) {
|
|
1034
|
-
const api = client || getAPIInstance();
|
|
1035
|
-
const response = await api.ext_support_support.ticketsList(params?.page, params?.page_size);
|
|
1036
|
-
try {
|
|
1037
|
-
return PaginatedTicketListSchema.parse(response);
|
|
1038
|
-
} catch (error) {
|
|
1039
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1040
|
-
consola.consola.box(`getSupportTicketsList
|
|
1041
|
-
Path: /cfg/support/tickets/
|
|
1042
|
-
Method: GET`);
|
|
1043
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1044
|
-
consola.consola.error("Validation Issues:");
|
|
1045
|
-
error.issues.forEach((issue, index) => {
|
|
1046
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1047
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1048
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1049
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1050
|
-
});
|
|
1051
|
-
}
|
|
1052
|
-
consola.consola.error("Response data:", response);
|
|
1053
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1054
|
-
try {
|
|
1055
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1056
|
-
detail: {
|
|
1057
|
-
operation: "getSupportTicketsList",
|
|
1058
|
-
path: "/cfg/support/tickets/",
|
|
1059
|
-
method: "GET",
|
|
1060
|
-
error,
|
|
1061
|
-
response,
|
|
1062
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1063
|
-
},
|
|
1064
|
-
bubbles: true,
|
|
1065
|
-
cancelable: false
|
|
1066
|
-
});
|
|
1067
|
-
window.dispatchEvent(event);
|
|
1068
|
-
} catch (eventError) {
|
|
1069
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
throw error;
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
async function createSupportTicketsCreate(data, client) {
|
|
1076
|
-
const api = client || getAPIInstance();
|
|
1077
|
-
const response = await api.ext_support_support.ticketsCreate(data);
|
|
1078
|
-
try {
|
|
1079
|
-
return TicketSchema.parse(response);
|
|
1080
|
-
} catch (error) {
|
|
1081
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1082
|
-
consola.consola.box(`createSupportTicketsCreate
|
|
1083
|
-
Path: /cfg/support/tickets/
|
|
1084
|
-
Method: POST`);
|
|
1085
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1086
|
-
consola.consola.error("Validation Issues:");
|
|
1087
|
-
error.issues.forEach((issue, index) => {
|
|
1088
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1089
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1090
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1091
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
consola.consola.error("Response data:", response);
|
|
1095
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1096
|
-
try {
|
|
1097
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1098
|
-
detail: {
|
|
1099
|
-
operation: "createSupportTicketsCreate",
|
|
1100
|
-
path: "/cfg/support/tickets/",
|
|
1101
|
-
method: "POST",
|
|
1102
|
-
error,
|
|
1103
|
-
response,
|
|
1104
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1105
|
-
},
|
|
1106
|
-
bubbles: true,
|
|
1107
|
-
cancelable: false
|
|
1108
|
-
});
|
|
1109
|
-
window.dispatchEvent(event);
|
|
1110
|
-
} catch (eventError) {
|
|
1111
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
throw error;
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
async function getSupportTicketsMessagesList(ticket_uuid, params, client) {
|
|
1118
|
-
const api = client || getAPIInstance();
|
|
1119
|
-
const response = await api.ext_support_support.ticketsMessagesList(ticket_uuid, params?.page, params?.page_size);
|
|
1120
|
-
try {
|
|
1121
|
-
return PaginatedMessageListSchema.parse(response);
|
|
1122
|
-
} catch (error) {
|
|
1123
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1124
|
-
consola.consola.box(`getSupportTicketsMessagesList
|
|
1125
|
-
Path: /cfg/support/tickets/{ticket_uuid}/messages/
|
|
1126
|
-
Method: GET`);
|
|
1127
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1128
|
-
consola.consola.error("Validation Issues:");
|
|
1129
|
-
error.issues.forEach((issue, index) => {
|
|
1130
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1131
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1132
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1133
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1134
|
-
});
|
|
1135
|
-
}
|
|
1136
|
-
consola.consola.error("Response data:", response);
|
|
1137
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1138
|
-
try {
|
|
1139
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1140
|
-
detail: {
|
|
1141
|
-
operation: "getSupportTicketsMessagesList",
|
|
1142
|
-
path: "/cfg/support/tickets/{ticket_uuid}/messages/",
|
|
1143
|
-
method: "GET",
|
|
1144
|
-
error,
|
|
1145
|
-
response,
|
|
1146
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1147
|
-
},
|
|
1148
|
-
bubbles: true,
|
|
1149
|
-
cancelable: false
|
|
1150
|
-
});
|
|
1151
|
-
window.dispatchEvent(event);
|
|
1152
|
-
} catch (eventError) {
|
|
1153
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
throw error;
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
async function createSupportTicketsMessagesCreate(ticket_uuid, data, client) {
|
|
1160
|
-
const api = client || getAPIInstance();
|
|
1161
|
-
const response = await api.ext_support_support.ticketsMessagesCreate(ticket_uuid, data);
|
|
1162
|
-
try {
|
|
1163
|
-
return MessageCreateSchema.parse(response);
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1166
|
-
consola.consola.box(`createSupportTicketsMessagesCreate
|
|
1167
|
-
Path: /cfg/support/tickets/{ticket_uuid}/messages/
|
|
1168
|
-
Method: POST`);
|
|
1169
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1170
|
-
consola.consola.error("Validation Issues:");
|
|
1171
|
-
error.issues.forEach((issue, index) => {
|
|
1172
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1173
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1174
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1175
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1176
|
-
});
|
|
1177
|
-
}
|
|
1178
|
-
consola.consola.error("Response data:", response);
|
|
1179
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1180
|
-
try {
|
|
1181
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1182
|
-
detail: {
|
|
1183
|
-
operation: "createSupportTicketsMessagesCreate",
|
|
1184
|
-
path: "/cfg/support/tickets/{ticket_uuid}/messages/",
|
|
1185
|
-
method: "POST",
|
|
1186
|
-
error,
|
|
1187
|
-
response,
|
|
1188
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1189
|
-
},
|
|
1190
|
-
bubbles: true,
|
|
1191
|
-
cancelable: false
|
|
1192
|
-
});
|
|
1193
|
-
window.dispatchEvent(event);
|
|
1194
|
-
} catch (eventError) {
|
|
1195
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
throw error;
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
async function getSupportTicketsMessagesRetrieve(ticket_uuid, uuid, client) {
|
|
1202
|
-
const api = client || getAPIInstance();
|
|
1203
|
-
const response = await api.ext_support_support.ticketsMessagesRetrieve(ticket_uuid, uuid);
|
|
1204
|
-
try {
|
|
1205
|
-
return MessageSchema.parse(response);
|
|
1206
|
-
} catch (error) {
|
|
1207
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1208
|
-
consola.consola.box(`getSupportTicketsMessagesRetrieve
|
|
1209
|
-
Path: /cfg/support/tickets/{ticket_uuid}/messages/{uuid}/
|
|
1210
|
-
Method: GET`);
|
|
1211
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1212
|
-
consola.consola.error("Validation Issues:");
|
|
1213
|
-
error.issues.forEach((issue, index) => {
|
|
1214
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1215
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1216
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1217
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1218
|
-
});
|
|
1219
|
-
}
|
|
1220
|
-
consola.consola.error("Response data:", response);
|
|
1221
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1222
|
-
try {
|
|
1223
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1224
|
-
detail: {
|
|
1225
|
-
operation: "getSupportTicketsMessagesRetrieve",
|
|
1226
|
-
path: "/cfg/support/tickets/{ticket_uuid}/messages/{uuid}/",
|
|
1227
|
-
method: "GET",
|
|
1228
|
-
error,
|
|
1229
|
-
response,
|
|
1230
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1231
|
-
},
|
|
1232
|
-
bubbles: true,
|
|
1233
|
-
cancelable: false
|
|
1234
|
-
});
|
|
1235
|
-
window.dispatchEvent(event);
|
|
1236
|
-
} catch (eventError) {
|
|
1237
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
throw error;
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
async function updateSupportTicketsMessagesUpdate(ticket_uuid, uuid, data, client) {
|
|
1244
|
-
const api = client || getAPIInstance();
|
|
1245
|
-
const response = await api.ext_support_support.ticketsMessagesUpdate(ticket_uuid, uuid, data);
|
|
1246
|
-
try {
|
|
1247
|
-
return MessageSchema.parse(response);
|
|
1248
|
-
} catch (error) {
|
|
1249
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1250
|
-
consola.consola.box(`updateSupportTicketsMessagesUpdate
|
|
1251
|
-
Path: /cfg/support/tickets/{ticket_uuid}/messages/{uuid}/
|
|
1252
|
-
Method: PUT`);
|
|
1253
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1254
|
-
consola.consola.error("Validation Issues:");
|
|
1255
|
-
error.issues.forEach((issue, index) => {
|
|
1256
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1257
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1258
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1259
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1260
|
-
});
|
|
1261
|
-
}
|
|
1262
|
-
consola.consola.error("Response data:", response);
|
|
1263
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1264
|
-
try {
|
|
1265
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1266
|
-
detail: {
|
|
1267
|
-
operation: "updateSupportTicketsMessagesUpdate",
|
|
1268
|
-
path: "/cfg/support/tickets/{ticket_uuid}/messages/{uuid}/",
|
|
1269
|
-
method: "PUT",
|
|
1270
|
-
error,
|
|
1271
|
-
response,
|
|
1272
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1273
|
-
},
|
|
1274
|
-
bubbles: true,
|
|
1275
|
-
cancelable: false
|
|
1276
|
-
});
|
|
1277
|
-
window.dispatchEvent(event);
|
|
1278
|
-
} catch (eventError) {
|
|
1279
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
throw error;
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
async function partialUpdateSupportTicketsMessagesPartialUpdate(ticket_uuid, uuid, data, client) {
|
|
1286
|
-
const api = client || getAPIInstance();
|
|
1287
|
-
const response = await api.ext_support_support.ticketsMessagesPartialUpdate(ticket_uuid, uuid, data);
|
|
1288
|
-
try {
|
|
1289
|
-
return MessageSchema.parse(response);
|
|
1290
|
-
} catch (error) {
|
|
1291
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1292
|
-
consola.consola.box(`partialUpdateSupportTicketsMessagesPartialUpdate
|
|
1293
|
-
Path: /cfg/support/tickets/{ticket_uuid}/messages/{uuid}/
|
|
1294
|
-
Method: PATCH`);
|
|
1295
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1296
|
-
consola.consola.error("Validation Issues:");
|
|
1297
|
-
error.issues.forEach((issue, index) => {
|
|
1298
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1299
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1300
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1301
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1302
|
-
});
|
|
1303
|
-
}
|
|
1304
|
-
consola.consola.error("Response data:", response);
|
|
1305
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1306
|
-
try {
|
|
1307
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1308
|
-
detail: {
|
|
1309
|
-
operation: "partialUpdateSupportTicketsMessagesPartialUpdate",
|
|
1310
|
-
path: "/cfg/support/tickets/{ticket_uuid}/messages/{uuid}/",
|
|
1311
|
-
method: "PATCH",
|
|
1312
|
-
error,
|
|
1313
|
-
response,
|
|
1314
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1315
|
-
},
|
|
1316
|
-
bubbles: true,
|
|
1317
|
-
cancelable: false
|
|
1318
|
-
});
|
|
1319
|
-
window.dispatchEvent(event);
|
|
1320
|
-
} catch (eventError) {
|
|
1321
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
throw error;
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
async function deleteSupportTicketsMessagesDestroy(ticket_uuid, uuid, client) {
|
|
1328
|
-
const api = client || getAPIInstance();
|
|
1329
|
-
const response = await api.ext_support_support.ticketsMessagesDestroy(ticket_uuid, uuid);
|
|
1330
|
-
return response;
|
|
1331
|
-
}
|
|
1332
|
-
async function getSupportTicketsRetrieve(uuid, client) {
|
|
1333
|
-
const api = client || getAPIInstance();
|
|
1334
|
-
const response = await api.ext_support_support.ticketsRetrieve(uuid);
|
|
1335
|
-
try {
|
|
1336
|
-
return TicketSchema.parse(response);
|
|
1337
|
-
} catch (error) {
|
|
1338
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1339
|
-
consola.consola.box(`getSupportTicketsRetrieve
|
|
1340
|
-
Path: /cfg/support/tickets/{uuid}/
|
|
1341
|
-
Method: GET`);
|
|
1342
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1343
|
-
consola.consola.error("Validation Issues:");
|
|
1344
|
-
error.issues.forEach((issue, index) => {
|
|
1345
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1346
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1347
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1348
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
|
-
consola.consola.error("Response data:", response);
|
|
1352
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1353
|
-
try {
|
|
1354
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1355
|
-
detail: {
|
|
1356
|
-
operation: "getSupportTicketsRetrieve",
|
|
1357
|
-
path: "/cfg/support/tickets/{uuid}/",
|
|
1358
|
-
method: "GET",
|
|
1359
|
-
error,
|
|
1360
|
-
response,
|
|
1361
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1362
|
-
},
|
|
1363
|
-
bubbles: true,
|
|
1364
|
-
cancelable: false
|
|
1365
|
-
});
|
|
1366
|
-
window.dispatchEvent(event);
|
|
1367
|
-
} catch (eventError) {
|
|
1368
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
throw error;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
async function updateSupportTicketsUpdate(uuid, data, client) {
|
|
1375
|
-
const api = client || getAPIInstance();
|
|
1376
|
-
const response = await api.ext_support_support.ticketsUpdate(uuid, data);
|
|
1377
|
-
try {
|
|
1378
|
-
return TicketSchema.parse(response);
|
|
1379
|
-
} catch (error) {
|
|
1380
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1381
|
-
consola.consola.box(`updateSupportTicketsUpdate
|
|
1382
|
-
Path: /cfg/support/tickets/{uuid}/
|
|
1383
|
-
Method: PUT`);
|
|
1384
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1385
|
-
consola.consola.error("Validation Issues:");
|
|
1386
|
-
error.issues.forEach((issue, index) => {
|
|
1387
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1388
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1389
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1390
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1391
|
-
});
|
|
1392
|
-
}
|
|
1393
|
-
consola.consola.error("Response data:", response);
|
|
1394
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1395
|
-
try {
|
|
1396
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1397
|
-
detail: {
|
|
1398
|
-
operation: "updateSupportTicketsUpdate",
|
|
1399
|
-
path: "/cfg/support/tickets/{uuid}/",
|
|
1400
|
-
method: "PUT",
|
|
1401
|
-
error,
|
|
1402
|
-
response,
|
|
1403
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1404
|
-
},
|
|
1405
|
-
bubbles: true,
|
|
1406
|
-
cancelable: false
|
|
1407
|
-
});
|
|
1408
|
-
window.dispatchEvent(event);
|
|
1409
|
-
} catch (eventError) {
|
|
1410
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
throw error;
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
async function partialUpdateSupportTicketsPartialUpdate(uuid, data, client) {
|
|
1417
|
-
const api = client || getAPIInstance();
|
|
1418
|
-
const response = await api.ext_support_support.ticketsPartialUpdate(uuid, data);
|
|
1419
|
-
try {
|
|
1420
|
-
return TicketSchema.parse(response);
|
|
1421
|
-
} catch (error) {
|
|
1422
|
-
consola.consola.error("\u274C Zod Validation Failed");
|
|
1423
|
-
consola.consola.box(`partialUpdateSupportTicketsPartialUpdate
|
|
1424
|
-
Path: /cfg/support/tickets/{uuid}/
|
|
1425
|
-
Method: PATCH`);
|
|
1426
|
-
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
1427
|
-
consola.consola.error("Validation Issues:");
|
|
1428
|
-
error.issues.forEach((issue, index) => {
|
|
1429
|
-
consola.consola.error(` ${index + 1}. ${issue.path.join(".") || "root"}`);
|
|
1430
|
-
consola.consola.error(` \u251C\u2500 Message: ${issue.message}`);
|
|
1431
|
-
if (issue.expected) consola.consola.error(` \u251C\u2500 Expected: ${issue.expected}`);
|
|
1432
|
-
if (issue.received) consola.consola.error(` \u2514\u2500 Received: ${issue.received}`);
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
consola.consola.error("Response data:", response);
|
|
1436
|
-
if (typeof window !== "undefined" && error instanceof Error && "issues" in error) {
|
|
1437
|
-
try {
|
|
1438
|
-
const event = new CustomEvent("zod-validation-error", {
|
|
1439
|
-
detail: {
|
|
1440
|
-
operation: "partialUpdateSupportTicketsPartialUpdate",
|
|
1441
|
-
path: "/cfg/support/tickets/{uuid}/",
|
|
1442
|
-
method: "PATCH",
|
|
1443
|
-
error,
|
|
1444
|
-
response,
|
|
1445
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1446
|
-
},
|
|
1447
|
-
bubbles: true,
|
|
1448
|
-
cancelable: false
|
|
1449
|
-
});
|
|
1450
|
-
window.dispatchEvent(event);
|
|
1451
|
-
} catch (eventError) {
|
|
1452
|
-
consola.consola.warn("Failed to dispatch validation error event:", eventError);
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
throw error;
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
async function deleteSupportTicketsDestroy(uuid, client) {
|
|
1459
|
-
const api = client || getAPIInstance();
|
|
1460
|
-
const response = await api.ext_support_support.ticketsDestroy(uuid);
|
|
1461
|
-
return response;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
// src/api/generated/ext_support/index.ts
|
|
1465
|
-
var TOKEN_KEY = "auth_token";
|
|
1466
|
-
var REFRESH_TOKEN_KEY = "refresh_token";
|
|
1467
|
-
var API = class {
|
|
1468
|
-
baseUrl;
|
|
1469
|
-
_client;
|
|
1470
|
-
_token = null;
|
|
1471
|
-
_refreshToken = null;
|
|
1472
|
-
storage;
|
|
1473
|
-
options;
|
|
1474
|
-
// Sub-clients
|
|
1475
|
-
ext_support_support;
|
|
1476
|
-
constructor(baseUrl, options) {
|
|
1477
|
-
this.baseUrl = baseUrl;
|
|
1478
|
-
this.options = options;
|
|
1479
|
-
const logger2 = options?.loggerConfig ? new APILogger(options.loggerConfig) : void 0;
|
|
1480
|
-
this.storage = options?.storage || new LocalStorageAdapter(logger2);
|
|
1481
|
-
this._loadTokensFromStorage();
|
|
1482
|
-
this._client = new APIClient(this.baseUrl, {
|
|
1483
|
-
retryConfig: this.options?.retryConfig,
|
|
1484
|
-
loggerConfig: this.options?.loggerConfig
|
|
1485
|
-
});
|
|
1486
|
-
this._injectAuthHeader();
|
|
1487
|
-
this.ext_support_support = this._client.ext_support_support;
|
|
1488
|
-
}
|
|
1489
|
-
_loadTokensFromStorage() {
|
|
1490
|
-
this._token = this.storage.getItem(TOKEN_KEY);
|
|
1491
|
-
this._refreshToken = this.storage.getItem(REFRESH_TOKEN_KEY);
|
|
1492
|
-
}
|
|
1493
|
-
_reinitClients() {
|
|
1494
|
-
this._client = new APIClient(this.baseUrl, {
|
|
1495
|
-
retryConfig: this.options?.retryConfig,
|
|
1496
|
-
loggerConfig: this.options?.loggerConfig
|
|
1497
|
-
});
|
|
1498
|
-
this._injectAuthHeader();
|
|
1499
|
-
this.ext_support_support = this._client.ext_support_support;
|
|
1500
|
-
}
|
|
1501
|
-
_injectAuthHeader() {
|
|
1502
|
-
const originalRequest = this._client.request.bind(this._client);
|
|
1503
|
-
this._client.request = async (method, path, options) => {
|
|
1504
|
-
const token = this.getToken();
|
|
1505
|
-
const mergedOptions = {
|
|
1506
|
-
...options,
|
|
1507
|
-
headers: {
|
|
1508
|
-
...options?.headers || {},
|
|
1509
|
-
...token ? { "Authorization": `Bearer ${token}` } : {}
|
|
1510
|
-
}
|
|
1511
|
-
};
|
|
1512
|
-
return originalRequest(method, path, mergedOptions);
|
|
1513
|
-
};
|
|
1514
|
-
}
|
|
1515
|
-
/**
|
|
1516
|
-
* Get current JWT token
|
|
1517
|
-
*/
|
|
1518
|
-
getToken() {
|
|
1519
|
-
return this.storage.getItem(TOKEN_KEY);
|
|
1520
|
-
}
|
|
1521
|
-
/**
|
|
1522
|
-
* Get current refresh token
|
|
1523
|
-
*/
|
|
1524
|
-
getRefreshToken() {
|
|
1525
|
-
return this.storage.getItem(REFRESH_TOKEN_KEY);
|
|
1526
|
-
}
|
|
1527
|
-
/**
|
|
1528
|
-
* Set JWT token and refresh token
|
|
1529
|
-
* @param token - JWT access token
|
|
1530
|
-
* @param refreshToken - JWT refresh token (optional)
|
|
1531
|
-
*/
|
|
1532
|
-
setToken(token, refreshToken) {
|
|
1533
|
-
this._token = token;
|
|
1534
|
-
this.storage.setItem(TOKEN_KEY, token);
|
|
1535
|
-
if (refreshToken) {
|
|
1536
|
-
this._refreshToken = refreshToken;
|
|
1537
|
-
this.storage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
|
1538
|
-
}
|
|
1539
|
-
this._reinitClients();
|
|
1540
|
-
}
|
|
1541
|
-
/**
|
|
1542
|
-
* Clear all tokens
|
|
1543
|
-
*/
|
|
1544
|
-
clearTokens() {
|
|
1545
|
-
this._token = null;
|
|
1546
|
-
this._refreshToken = null;
|
|
1547
|
-
this.storage.removeItem(TOKEN_KEY);
|
|
1548
|
-
this.storage.removeItem(REFRESH_TOKEN_KEY);
|
|
1549
|
-
this._reinitClients();
|
|
1550
|
-
}
|
|
1551
|
-
/**
|
|
1552
|
-
* Check if user is authenticated
|
|
1553
|
-
*/
|
|
1554
|
-
isAuthenticated() {
|
|
1555
|
-
return !!this.getToken();
|
|
1556
|
-
}
|
|
1557
|
-
/**
|
|
1558
|
-
* Update base URL and reinitialize clients
|
|
1559
|
-
* @param url - New base URL
|
|
1560
|
-
*/
|
|
1561
|
-
setBaseUrl(url) {
|
|
1562
|
-
this.baseUrl = url;
|
|
1563
|
-
this._reinitClients();
|
|
1564
|
-
}
|
|
1565
|
-
/**
|
|
1566
|
-
* Get current base URL
|
|
1567
|
-
*/
|
|
1568
|
-
getBaseUrl() {
|
|
1569
|
-
return this.baseUrl;
|
|
1570
|
-
}
|
|
1571
|
-
/**
|
|
1572
|
-
* Get OpenAPI schema path
|
|
1573
|
-
* @returns Path to the OpenAPI schema JSON file
|
|
1574
|
-
*
|
|
1575
|
-
* Note: The OpenAPI schema is available in the schema.json file.
|
|
1576
|
-
* You can load it dynamically using:
|
|
1577
|
-
* ```typescript
|
|
1578
|
-
* const schema = await fetch('./schema.json').then(r => r.json());
|
|
1579
|
-
* // or using fs in Node.js:
|
|
1580
|
-
* // const schema = JSON.parse(fs.readFileSync('./schema.json', 'utf-8'));
|
|
1581
|
-
* ```
|
|
1582
|
-
*/
|
|
1583
|
-
getSchemaPath() {
|
|
1584
|
-
return "./schema.json";
|
|
1585
|
-
}
|
|
1586
|
-
};
|
|
1587
|
-
var apiSupport = api.createExtensionAPI(API);
|
|
1588
|
-
function useSupportTicketsList(params, client) {
|
|
1589
|
-
return useSWR__default.default(
|
|
1590
|
-
params ? ["cfg-support-tickets", params] : "cfg-support-tickets",
|
|
1591
|
-
() => getSupportTicketsList(params, client)
|
|
1592
|
-
);
|
|
1593
|
-
}
|
|
1594
|
-
function useCreateSupportTicketsCreate() {
|
|
1595
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1596
|
-
return async (data, client) => {
|
|
1597
|
-
const result = await createSupportTicketsCreate(data, client);
|
|
1598
|
-
mutate("cfg-support-tickets");
|
|
1599
|
-
return result;
|
|
1600
|
-
};
|
|
1601
|
-
}
|
|
1602
|
-
function useSupportTicketsMessagesList(ticket_uuid, params, client) {
|
|
1603
|
-
return useSWR__default.default(
|
|
1604
|
-
["cfg-support-tickets-messages", ticket_uuid],
|
|
1605
|
-
() => getSupportTicketsMessagesList(ticket_uuid, params, client)
|
|
1606
|
-
);
|
|
1607
|
-
}
|
|
1608
|
-
function useCreateSupportTicketsMessagesCreate() {
|
|
1609
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1610
|
-
return async (ticket_uuid, data, client) => {
|
|
1611
|
-
const result = await createSupportTicketsMessagesCreate(ticket_uuid, data, client);
|
|
1612
|
-
mutate("cfg-support-tickets-messages");
|
|
1613
|
-
return result;
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
function useSupportTicketsMessagesRetrieve(ticket_uuid, uuid, client) {
|
|
1617
|
-
return useSWR__default.default(
|
|
1618
|
-
["cfg-support-tickets-message", ticket_uuid],
|
|
1619
|
-
() => getSupportTicketsMessagesRetrieve(ticket_uuid, uuid, client)
|
|
1620
|
-
);
|
|
1621
|
-
}
|
|
1622
|
-
function useUpdateSupportTicketsMessagesUpdate() {
|
|
1623
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1624
|
-
return async (ticket_uuid, uuid, data, client) => {
|
|
1625
|
-
const result = await updateSupportTicketsMessagesUpdate(ticket_uuid, uuid, data, client);
|
|
1626
|
-
mutate("cfg-support-tickets-messages");
|
|
1627
|
-
mutate("cfg-support-tickets-message");
|
|
1628
|
-
return result;
|
|
1629
|
-
};
|
|
1630
|
-
}
|
|
1631
|
-
function usePartialUpdateSupportTicketsMessagesPartialUpdate() {
|
|
1632
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1633
|
-
return async (ticket_uuid, uuid, data, client) => {
|
|
1634
|
-
const result = await partialUpdateSupportTicketsMessagesPartialUpdate(ticket_uuid, uuid, data, client);
|
|
1635
|
-
mutate("cfg-support-tickets-messages-partial");
|
|
1636
|
-
return result;
|
|
1637
|
-
};
|
|
1638
|
-
}
|
|
1639
|
-
function useDeleteSupportTicketsMessagesDestroy() {
|
|
1640
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1641
|
-
return async (ticket_uuid, uuid, client) => {
|
|
1642
|
-
const result = await deleteSupportTicketsMessagesDestroy(ticket_uuid, uuid, client);
|
|
1643
|
-
mutate("cfg-support-tickets-messages");
|
|
1644
|
-
mutate("cfg-support-tickets-message");
|
|
1645
|
-
return result;
|
|
1646
|
-
};
|
|
1647
|
-
}
|
|
1648
|
-
function useSupportTicketsRetrieve(uuid, client) {
|
|
1649
|
-
return useSWR__default.default(
|
|
1650
|
-
["cfg-support-ticket", uuid],
|
|
1651
|
-
() => getSupportTicketsRetrieve(uuid, client)
|
|
1652
|
-
);
|
|
1653
|
-
}
|
|
1654
|
-
function useUpdateSupportTicketsUpdate() {
|
|
1655
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1656
|
-
return async (uuid, data, client) => {
|
|
1657
|
-
const result = await updateSupportTicketsUpdate(uuid, data, client);
|
|
1658
|
-
mutate("cfg-support-tickets");
|
|
1659
|
-
mutate("cfg-support-ticket");
|
|
1660
|
-
return result;
|
|
1661
|
-
};
|
|
1662
|
-
}
|
|
1663
|
-
function usePartialUpdateSupportTicketsPartialUpdate() {
|
|
1664
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1665
|
-
return async (uuid, data, client) => {
|
|
1666
|
-
const result = await partialUpdateSupportTicketsPartialUpdate(uuid, data, client);
|
|
1667
|
-
mutate("cfg-support-tickets-partial");
|
|
1668
|
-
return result;
|
|
1669
|
-
};
|
|
1670
|
-
}
|
|
1671
|
-
function useDeleteSupportTicketsDestroy() {
|
|
1672
|
-
const { mutate } = useSWR.useSWRConfig();
|
|
1673
|
-
return async (uuid, client) => {
|
|
1674
|
-
const result = await deleteSupportTicketsDestroy(uuid, client);
|
|
1675
|
-
mutate("cfg-support-tickets");
|
|
1676
|
-
mutate("cfg-support-ticket");
|
|
1677
|
-
return result;
|
|
1678
|
-
};
|
|
1679
|
-
}
|
|
1680
|
-
var SupportContext = React7.createContext(void 0);
|
|
1681
|
-
function SupportProvider({ children }) {
|
|
1682
|
-
const {
|
|
1683
|
-
data: ticketsData,
|
|
1684
|
-
error: ticketsError,
|
|
1685
|
-
isLoading: isLoadingTickets,
|
|
1686
|
-
mutate: mutateTickets
|
|
1687
|
-
} = useSupportTicketsList({ page: 1, page_size: 1 });
|
|
1688
|
-
const refreshTickets = async () => {
|
|
1689
|
-
await mutateTickets();
|
|
1690
|
-
};
|
|
1691
|
-
const createTicketMutation = useCreateSupportTicketsCreate();
|
|
1692
|
-
const updateTicketMutation = useUpdateSupportTicketsUpdate();
|
|
1693
|
-
usePartialUpdateSupportTicketsPartialUpdate();
|
|
1694
|
-
const deleteTicketMutation = useDeleteSupportTicketsDestroy();
|
|
1695
|
-
const createMessageMutation = useCreateSupportTicketsMessagesCreate();
|
|
1696
|
-
const updateMessageMutation = useUpdateSupportTicketsMessagesUpdate();
|
|
1697
|
-
usePartialUpdateSupportTicketsMessagesPartialUpdate();
|
|
1698
|
-
const deleteMessageMutation = useDeleteSupportTicketsMessagesDestroy();
|
|
1699
|
-
const getTicket = async (uuid) => {
|
|
1700
|
-
const { data } = useSupportTicketsRetrieve(uuid);
|
|
1701
|
-
return data;
|
|
1702
|
-
};
|
|
1703
|
-
const createTicket = async (data) => {
|
|
1704
|
-
const result = await createTicketMutation(data);
|
|
1705
|
-
await refreshTickets();
|
|
1706
|
-
return result;
|
|
1707
|
-
};
|
|
1708
|
-
const updateTicket = async (uuid, data) => {
|
|
1709
|
-
const result = await updateTicketMutation(uuid, data);
|
|
1710
|
-
await refreshTickets();
|
|
1711
|
-
return result;
|
|
1712
|
-
};
|
|
1713
|
-
const partialUpdateTicket = async (uuid, data) => {
|
|
1714
|
-
const result = await updateTicketMutation(uuid, data);
|
|
1715
|
-
await refreshTickets();
|
|
1716
|
-
return result;
|
|
1717
|
-
};
|
|
1718
|
-
const deleteTicket = async (uuid) => {
|
|
1719
|
-
await deleteTicketMutation(uuid);
|
|
1720
|
-
await refreshTickets();
|
|
1721
|
-
};
|
|
1722
|
-
const getMessages = async (ticketUuid) => {
|
|
1723
|
-
const { data } = useSupportTicketsMessagesList(ticketUuid, { page: 1, page_size: 100 });
|
|
1724
|
-
return data?.results;
|
|
1725
|
-
};
|
|
1726
|
-
const getMessage = async (ticketUuid, messageUuid) => {
|
|
1727
|
-
const { data } = useSupportTicketsMessagesRetrieve(
|
|
1728
|
-
ticketUuid,
|
|
1729
|
-
messageUuid
|
|
1730
|
-
);
|
|
1731
|
-
return data;
|
|
1732
|
-
};
|
|
1733
|
-
const createMessage = async (ticketUuid, data) => {
|
|
1734
|
-
const result = await createMessageMutation(ticketUuid, data);
|
|
1735
|
-
return result;
|
|
1736
|
-
};
|
|
1737
|
-
const updateMessage = async (ticketUuid, messageUuid, data) => {
|
|
1738
|
-
const result = await updateMessageMutation(
|
|
1739
|
-
ticketUuid,
|
|
1740
|
-
messageUuid,
|
|
1741
|
-
data
|
|
1742
|
-
);
|
|
1743
|
-
return result;
|
|
1744
|
-
};
|
|
1745
|
-
const partialUpdateMessage = async (ticketUuid, messageUuid, data) => {
|
|
1746
|
-
const result = await updateMessageMutation(
|
|
1747
|
-
ticketUuid,
|
|
1748
|
-
messageUuid,
|
|
1749
|
-
data
|
|
1750
|
-
);
|
|
1751
|
-
return result;
|
|
1752
|
-
};
|
|
1753
|
-
const deleteMessage = async (ticketUuid, messageUuid) => {
|
|
1754
|
-
await deleteMessageMutation(ticketUuid, messageUuid);
|
|
1755
|
-
};
|
|
1756
|
-
const refreshMessages = async (ticketUuid) => {
|
|
1757
|
-
await refreshTickets();
|
|
1758
|
-
};
|
|
1759
|
-
const value = {
|
|
1760
|
-
tickets: ticketsData?.results,
|
|
1761
|
-
isLoadingTickets,
|
|
1762
|
-
ticketsError,
|
|
1763
|
-
refreshTickets,
|
|
1764
|
-
getTicket,
|
|
1765
|
-
createTicket,
|
|
1766
|
-
updateTicket,
|
|
1767
|
-
partialUpdateTicket,
|
|
1768
|
-
deleteTicket,
|
|
1769
|
-
getMessages,
|
|
1770
|
-
getMessage,
|
|
1771
|
-
createMessage,
|
|
1772
|
-
updateMessage,
|
|
1773
|
-
partialUpdateMessage,
|
|
1774
|
-
deleteMessage,
|
|
1775
|
-
refreshMessages
|
|
1776
|
-
};
|
|
1777
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SupportContext.Provider, { value, children });
|
|
1778
|
-
}
|
|
1779
|
-
function useSupportContext() {
|
|
1780
|
-
const context = React7.useContext(SupportContext);
|
|
1781
|
-
if (!context) {
|
|
1782
|
-
throw new Error("useSupportContext must be used within SupportProvider");
|
|
1783
|
-
}
|
|
1784
|
-
return context;
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
// src/layouts/SupportLayout/events.ts
|
|
1788
|
-
var SUPPORT_LAYOUT_EVENTS = {
|
|
1789
|
-
// Dialog events
|
|
1790
|
-
OPEN_CREATE_DIALOG: "support-layout:open-create-dialog",
|
|
1791
|
-
CLOSE_CREATE_DIALOG: "support-layout:close-create-dialog",
|
|
1792
|
-
// Ticket events
|
|
1793
|
-
TICKET_SELECTED: "support-layout:ticket-selected",
|
|
1794
|
-
TICKET_CREATED: "support-layout:ticket-created",
|
|
1795
|
-
// Message events
|
|
1796
|
-
MESSAGE_SENT: "support-layout:message-sent"
|
|
1797
|
-
};
|
|
1798
|
-
var openCreateTicketDialog = () => {
|
|
1799
|
-
if (typeof window !== "undefined") {
|
|
1800
|
-
window.dispatchEvent(new CustomEvent(SUPPORT_LAYOUT_EVENTS.OPEN_CREATE_DIALOG));
|
|
1801
|
-
}
|
|
1802
|
-
};
|
|
1803
|
-
var closeCreateTicketDialog = () => {
|
|
1804
|
-
if (typeof window !== "undefined") {
|
|
1805
|
-
window.dispatchEvent(new CustomEvent(SUPPORT_LAYOUT_EVENTS.CLOSE_CREATE_DIALOG));
|
|
1806
|
-
}
|
|
1807
|
-
};
|
|
1808
|
-
var PAGE_SIZE = 20;
|
|
1809
|
-
function useInfiniteTickets() {
|
|
1810
|
-
const getKey = (pageIndex, previousPageData) => {
|
|
1811
|
-
if (previousPageData && !previousPageData.has_next) return null;
|
|
1812
|
-
if (pageIndex === 0) return ["cfg-support-tickets-infinite", 1, PAGE_SIZE];
|
|
1813
|
-
return ["cfg-support-tickets-infinite", pageIndex + 1, PAGE_SIZE];
|
|
1814
|
-
};
|
|
1815
|
-
const fetcher = async ([, page, pageSize]) => {
|
|
1816
|
-
return getSupportTicketsList(
|
|
1817
|
-
{ page, page_size: pageSize }
|
|
1818
|
-
);
|
|
1819
|
-
};
|
|
1820
|
-
const {
|
|
1821
|
-
data,
|
|
1822
|
-
error,
|
|
1823
|
-
isLoading,
|
|
1824
|
-
isValidating,
|
|
1825
|
-
size,
|
|
1826
|
-
setSize,
|
|
1827
|
-
mutate
|
|
1828
|
-
} = useSWRInfinite__default.default(getKey, fetcher, {
|
|
1829
|
-
revalidateFirstPage: false,
|
|
1830
|
-
parallel: false
|
|
1831
|
-
});
|
|
1832
|
-
const tickets = data ? data.flatMap((page) => page.results) : [];
|
|
1833
|
-
const hasMore = data && data[data.length - 1]?.has_next;
|
|
1834
|
-
const totalCount = data && data[data.length - 1]?.count;
|
|
1835
|
-
const isLoadingMore = isValidating && data && typeof data[size - 1] !== "undefined";
|
|
1836
|
-
const loadMore = () => {
|
|
1837
|
-
if (hasMore && !isLoadingMore) {
|
|
1838
|
-
setSize(size + 1);
|
|
1839
|
-
}
|
|
1840
|
-
};
|
|
1841
|
-
const refresh = async () => {
|
|
1842
|
-
await mutate();
|
|
1843
|
-
};
|
|
1844
|
-
return {
|
|
1845
|
-
tickets,
|
|
1846
|
-
isLoading,
|
|
1847
|
-
isLoadingMore: isLoadingMore || false,
|
|
1848
|
-
error,
|
|
1849
|
-
hasMore: hasMore || false,
|
|
1850
|
-
totalCount: totalCount || 0,
|
|
1851
|
-
loadMore,
|
|
1852
|
-
refresh
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
var PAGE_SIZE2 = 20;
|
|
1856
|
-
function useInfiniteMessages(ticketUuid) {
|
|
1857
|
-
const getKey = (pageIndex, previousPageData) => {
|
|
1858
|
-
if (!ticketUuid) return null;
|
|
1859
|
-
if (previousPageData && !previousPageData.has_next) return null;
|
|
1860
|
-
if (pageIndex === 0) return ["cfg-support-messages-infinite", ticketUuid, 1, PAGE_SIZE2];
|
|
1861
|
-
return ["cfg-support-messages-infinite", ticketUuid, pageIndex + 1, PAGE_SIZE2];
|
|
1862
|
-
};
|
|
1863
|
-
const fetcher = async ([, ticket_uuid, page, pageSize]) => {
|
|
1864
|
-
return getSupportTicketsMessagesList(
|
|
1865
|
-
ticket_uuid,
|
|
1866
|
-
{ page, page_size: pageSize }
|
|
1867
|
-
);
|
|
1868
|
-
};
|
|
1869
|
-
const {
|
|
1870
|
-
data,
|
|
1871
|
-
error,
|
|
1872
|
-
isLoading,
|
|
1873
|
-
isValidating,
|
|
1874
|
-
size,
|
|
1875
|
-
setSize,
|
|
1876
|
-
mutate
|
|
1877
|
-
} = useSWRInfinite__default.default(getKey, fetcher, {
|
|
1878
|
-
revalidateFirstPage: false,
|
|
1879
|
-
parallel: false
|
|
1880
|
-
});
|
|
1881
|
-
const messages = data ? data.flatMap((page) => page.results) : [];
|
|
1882
|
-
const hasMore = data && data[data.length - 1]?.has_next;
|
|
1883
|
-
const totalCount = data && data[data.length - 1]?.count;
|
|
1884
|
-
const isLoadingMore = !!(isValidating && data && typeof data[size - 1] !== "undefined");
|
|
1885
|
-
const loadMore = () => {
|
|
1886
|
-
if (hasMore && !isLoadingMore) {
|
|
1887
|
-
setSize(size + 1);
|
|
1888
|
-
}
|
|
1889
|
-
};
|
|
1890
|
-
const refresh = async () => {
|
|
1891
|
-
await mutate();
|
|
1892
|
-
};
|
|
1893
|
-
const addMessage = (message) => {
|
|
1894
|
-
if (!data || !data[0]) return;
|
|
1895
|
-
const newData = [...data];
|
|
1896
|
-
const firstPage = newData[0];
|
|
1897
|
-
if (firstPage) {
|
|
1898
|
-
newData[0] = {
|
|
1899
|
-
...firstPage,
|
|
1900
|
-
results: [message, ...firstPage.results],
|
|
1901
|
-
count: firstPage.count + 1,
|
|
1902
|
-
page: firstPage.page || 1,
|
|
1903
|
-
pages: firstPage.pages || 1
|
|
1904
|
-
};
|
|
1905
|
-
}
|
|
1906
|
-
mutate(newData, false);
|
|
1907
|
-
};
|
|
1908
|
-
return {
|
|
1909
|
-
messages,
|
|
1910
|
-
isLoading,
|
|
1911
|
-
isLoadingMore: isLoadingMore || false,
|
|
1912
|
-
error,
|
|
1913
|
-
hasMore: hasMore || false,
|
|
1914
|
-
totalCount: totalCount || 0,
|
|
1915
|
-
loadMore,
|
|
1916
|
-
refresh,
|
|
1917
|
-
addMessage
|
|
1918
|
-
};
|
|
1919
|
-
}
|
|
1920
|
-
var SupportLayoutContext = React7.createContext(void 0);
|
|
1921
|
-
function SupportLayoutProvider({ children }) {
|
|
1922
|
-
const support = useSupportContext();
|
|
1923
|
-
const { user } = auth.useAuth();
|
|
1924
|
-
const [uiState, setUIState] = React7.useState({
|
|
1925
|
-
selectedTicketUuid: null,
|
|
1926
|
-
isCreateDialogOpen: false,
|
|
1927
|
-
viewMode: "list"
|
|
1928
|
-
});
|
|
1929
|
-
const selectedTicket = support.tickets?.find((t) => t.uuid === uiState.selectedTicketUuid);
|
|
1930
|
-
const {
|
|
1931
|
-
messages: selectedTicketMessages,
|
|
1932
|
-
isLoading: isLoadingMessages,
|
|
1933
|
-
isLoadingMore: isLoadingMoreMessages,
|
|
1934
|
-
hasMore: hasMoreMessages,
|
|
1935
|
-
totalCount: totalMessagesCount,
|
|
1936
|
-
loadMore: loadMoreMessages,
|
|
1937
|
-
refresh: refreshMessages,
|
|
1938
|
-
addMessage: addMessageOptimistically
|
|
1939
|
-
} = useInfiniteMessages(selectedTicket?.uuid || null);
|
|
1940
|
-
const selectTicket = React7.useCallback(async (ticket) => {
|
|
1941
|
-
setUIState((prev) => ({ ...prev, selectedTicketUuid: ticket?.uuid || null }));
|
|
1942
|
-
if (ticket?.uuid) {
|
|
1943
|
-
window.dispatchEvent(
|
|
1944
|
-
new CustomEvent(SUPPORT_LAYOUT_EVENTS.TICKET_SELECTED, { detail: { ticket } })
|
|
1945
|
-
);
|
|
1946
|
-
}
|
|
1947
|
-
}, []);
|
|
1948
|
-
const createTicket = React7.useCallback(async (data) => {
|
|
1949
|
-
if (!user?.id) {
|
|
1950
|
-
throw new Error("User must be authenticated to create tickets");
|
|
1951
|
-
}
|
|
1952
|
-
const ticket = await support.createTicket({
|
|
1953
|
-
user: user.id,
|
|
1954
|
-
subject: data.subject
|
|
1955
|
-
});
|
|
1956
|
-
if (ticket.uuid && data.message) {
|
|
1957
|
-
await support.createMessage(ticket.uuid, {
|
|
1958
|
-
text: data.message
|
|
1959
|
-
});
|
|
1960
|
-
}
|
|
1961
|
-
setUIState((prev) => ({ ...prev, isCreateDialogOpen: false }));
|
|
1962
|
-
await support.refreshTickets();
|
|
1963
|
-
window.dispatchEvent(
|
|
1964
|
-
new CustomEvent(SUPPORT_LAYOUT_EVENTS.TICKET_CREATED, { detail: { ticket } })
|
|
1965
|
-
);
|
|
1966
|
-
setUIState((prev) => ({ ...prev, selectedTicketUuid: ticket.uuid }));
|
|
1967
|
-
window.dispatchEvent(
|
|
1968
|
-
new CustomEvent(SUPPORT_LAYOUT_EVENTS.TICKET_SELECTED, { detail: { ticket } })
|
|
1969
|
-
);
|
|
1970
|
-
}, [support, user]);
|
|
1971
|
-
const sendMessage = React7.useCallback(async (message) => {
|
|
1972
|
-
if (!selectedTicket?.uuid) return;
|
|
1973
|
-
const messageData = {
|
|
1974
|
-
text: message
|
|
1975
|
-
};
|
|
1976
|
-
const newMessage = await support.createMessage(selectedTicket.uuid, messageData);
|
|
1977
|
-
if (newMessage) {
|
|
1978
|
-
const fullMessage = {
|
|
1979
|
-
uuid: newMessage.uuid || `temp-${Date.now()}`,
|
|
1980
|
-
ticket: selectedTicket.uuid,
|
|
1981
|
-
sender: {
|
|
1982
|
-
id: user?.id || 0,
|
|
1983
|
-
display_username: user?.display_username || "",
|
|
1984
|
-
email: user?.email || "",
|
|
1985
|
-
avatar: user?.avatar || null,
|
|
1986
|
-
initials: user?.initials || "",
|
|
1987
|
-
is_staff: user?.is_staff || false,
|
|
1988
|
-
is_superuser: user?.is_superuser || false
|
|
1989
|
-
},
|
|
1990
|
-
is_from_author: true,
|
|
1991
|
-
text: message,
|
|
1992
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1993
|
-
};
|
|
1994
|
-
addMessageOptimistically(fullMessage);
|
|
1995
|
-
}
|
|
1996
|
-
await refreshMessages();
|
|
1997
|
-
window.dispatchEvent(
|
|
1998
|
-
new CustomEvent(SUPPORT_LAYOUT_EVENTS.MESSAGE_SENT, { detail: { message: newMessage } })
|
|
1999
|
-
);
|
|
2000
|
-
}, [selectedTicket, support, user, addMessageOptimistically, refreshMessages]);
|
|
2001
|
-
const openCreateDialog = React7.useCallback(() => {
|
|
2002
|
-
setUIState((prev) => ({ ...prev, isCreateDialogOpen: true }));
|
|
2003
|
-
}, []);
|
|
2004
|
-
const closeCreateDialog = React7.useCallback(() => {
|
|
2005
|
-
setUIState((prev) => ({ ...prev, isCreateDialogOpen: false }));
|
|
2006
|
-
}, []);
|
|
2007
|
-
const getUnreadCount = React7.useCallback(() => {
|
|
2008
|
-
return support.tickets?.reduce((count, ticket) => count + (ticket.unanswered_messages_count || 0), 0) || 0;
|
|
2009
|
-
}, [support.tickets]);
|
|
2010
|
-
React7.useEffect(() => {
|
|
2011
|
-
const handleOpenDialog = () => openCreateDialog();
|
|
2012
|
-
const handleCloseDialog = () => closeCreateDialog();
|
|
2013
|
-
window.addEventListener(SUPPORT_LAYOUT_EVENTS.OPEN_CREATE_DIALOG, handleOpenDialog);
|
|
2014
|
-
window.addEventListener(SUPPORT_LAYOUT_EVENTS.CLOSE_CREATE_DIALOG, handleCloseDialog);
|
|
2015
|
-
return () => {
|
|
2016
|
-
window.removeEventListener(SUPPORT_LAYOUT_EVENTS.OPEN_CREATE_DIALOG, handleOpenDialog);
|
|
2017
|
-
window.removeEventListener(SUPPORT_LAYOUT_EVENTS.CLOSE_CREATE_DIALOG, handleCloseDialog);
|
|
2018
|
-
};
|
|
2019
|
-
}, [openCreateDialog, closeCreateDialog]);
|
|
2020
|
-
const value = {
|
|
2021
|
-
tickets: support.tickets,
|
|
2022
|
-
isLoadingTickets: support.isLoadingTickets,
|
|
2023
|
-
ticketsError: support.ticketsError,
|
|
2024
|
-
selectedTicket,
|
|
2025
|
-
selectedTicketMessages,
|
|
2026
|
-
isLoadingMessages,
|
|
2027
|
-
isLoadingMoreMessages,
|
|
2028
|
-
hasMoreMessages,
|
|
2029
|
-
totalMessagesCount,
|
|
2030
|
-
loadMoreMessages,
|
|
2031
|
-
uiState,
|
|
2032
|
-
selectTicket,
|
|
2033
|
-
createTicket,
|
|
2034
|
-
sendMessage,
|
|
2035
|
-
refreshTickets: support.refreshTickets,
|
|
2036
|
-
refreshMessages,
|
|
2037
|
-
openCreateDialog,
|
|
2038
|
-
closeCreateDialog,
|
|
2039
|
-
getUnreadCount
|
|
2040
|
-
};
|
|
2041
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SupportLayoutContext.Provider, { value, children });
|
|
2042
|
-
}
|
|
2043
|
-
function useSupportLayoutContext() {
|
|
2044
|
-
const context = React7.useContext(SupportLayoutContext);
|
|
2045
|
-
if (!context) {
|
|
2046
|
-
throw new Error("useSupportLayoutContext must be used within SupportLayoutProvider");
|
|
2047
|
-
}
|
|
2048
|
-
return context;
|
|
2049
|
-
}
|
|
2050
|
-
var getStatusBadgeVariant = (status) => {
|
|
2051
|
-
switch (status) {
|
|
2052
|
-
case "open":
|
|
2053
|
-
return "default";
|
|
2054
|
-
case "waiting_for_user":
|
|
2055
|
-
return "secondary";
|
|
2056
|
-
case "waiting_for_admin":
|
|
2057
|
-
return "outline";
|
|
2058
|
-
case "resolved":
|
|
2059
|
-
return "outline";
|
|
2060
|
-
case "closed":
|
|
2061
|
-
return "secondary";
|
|
2062
|
-
default:
|
|
2063
|
-
return "default";
|
|
2064
|
-
}
|
|
2065
|
-
};
|
|
2066
|
-
var formatRelativeTime = (date) => {
|
|
2067
|
-
if (!date) return "N/A";
|
|
2068
|
-
const now = /* @__PURE__ */ new Date();
|
|
2069
|
-
const messageDate = new Date(date);
|
|
2070
|
-
const diffInSeconds = Math.floor((now.getTime() - messageDate.getTime()) / 1e3);
|
|
2071
|
-
if (diffInSeconds < 60) return "Just now";
|
|
2072
|
-
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
|
|
2073
|
-
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
|
|
2074
|
-
if (diffInSeconds < 604800) return `${Math.floor(diffInSeconds / 86400)}d ago`;
|
|
2075
|
-
return new Date(date).toLocaleDateString("en-US", {
|
|
2076
|
-
year: "numeric",
|
|
2077
|
-
month: "short",
|
|
2078
|
-
day: "numeric"
|
|
2079
|
-
});
|
|
2080
|
-
};
|
|
2081
|
-
var TicketCard = ({ ticket, isSelected, onClick }) => {
|
|
2082
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2083
|
-
uiNextjs.Card,
|
|
2084
|
-
{
|
|
2085
|
-
className: uiNextjs.cn(
|
|
2086
|
-
"cursor-pointer transition-all duration-200 ease-out",
|
|
2087
|
-
"hover:bg-accent/50 hover:shadow-md hover:scale-[1.02]",
|
|
2088
|
-
"active:scale-[0.98]",
|
|
2089
|
-
isSelected && "bg-accent border-primary shadow-sm"
|
|
2090
|
-
),
|
|
2091
|
-
onClick,
|
|
2092
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.CardContent, { className: "p-4", children: [
|
|
2093
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-2", children: [
|
|
2094
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-sm line-clamp-2 flex-1", children: ticket.subject }),
|
|
2095
|
-
(ticket.unanswered_messages_count || 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2096
|
-
uiNextjs.Badge,
|
|
2097
|
-
{
|
|
2098
|
-
variant: "destructive",
|
|
2099
|
-
className: "ml-2 shrink-0 animate-pulse",
|
|
2100
|
-
children: ticket.unanswered_messages_count
|
|
2101
|
-
}
|
|
2102
|
-
)
|
|
2103
|
-
] }),
|
|
2104
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2105
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Badge, { variant: getStatusBadgeVariant(ticket.status || "open"), className: "text-xs", children: ticket.status || "open" }),
|
|
2106
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2107
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3 w-3" }),
|
|
2108
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatRelativeTime(ticket.created_at) })
|
|
2109
|
-
] })
|
|
2110
|
-
] }) })
|
|
2111
|
-
] })
|
|
2112
|
-
}
|
|
2113
|
-
);
|
|
2114
|
-
};
|
|
2115
|
-
var TicketList = () => {
|
|
2116
|
-
const { selectedTicket, selectTicket } = useSupportLayoutContext();
|
|
2117
|
-
const {
|
|
2118
|
-
tickets,
|
|
2119
|
-
isLoading,
|
|
2120
|
-
isLoadingMore,
|
|
2121
|
-
hasMore,
|
|
2122
|
-
loadMore,
|
|
2123
|
-
totalCount,
|
|
2124
|
-
refresh
|
|
2125
|
-
} = useInfiniteTickets();
|
|
2126
|
-
const scrollRef = React7.useRef(null);
|
|
2127
|
-
const observerRef = React7.useRef(null);
|
|
2128
|
-
const loadMoreRef = React7.useRef(null);
|
|
2129
|
-
React7.useEffect(() => {
|
|
2130
|
-
const handleTicketCreated = () => {
|
|
2131
|
-
refresh();
|
|
2132
|
-
};
|
|
2133
|
-
window.addEventListener(SUPPORT_LAYOUT_EVENTS.TICKET_CREATED, handleTicketCreated);
|
|
2134
|
-
return () => {
|
|
2135
|
-
window.removeEventListener(SUPPORT_LAYOUT_EVENTS.TICKET_CREATED, handleTicketCreated);
|
|
2136
|
-
};
|
|
2137
|
-
}, [refresh]);
|
|
2138
|
-
React7.useEffect(() => {
|
|
2139
|
-
if (observerRef.current) {
|
|
2140
|
-
observerRef.current.disconnect();
|
|
2141
|
-
}
|
|
2142
|
-
observerRef.current = new IntersectionObserver(
|
|
2143
|
-
(entries) => {
|
|
2144
|
-
if (entries[0]?.isIntersecting && hasMore && !isLoadingMore) {
|
|
2145
|
-
loadMore();
|
|
2146
|
-
}
|
|
2147
|
-
},
|
|
2148
|
-
{ threshold: 0.1 }
|
|
2149
|
-
);
|
|
2150
|
-
if (loadMoreRef.current) {
|
|
2151
|
-
observerRef.current.observe(loadMoreRef.current);
|
|
2152
|
-
}
|
|
2153
|
-
return () => {
|
|
2154
|
-
if (observerRef.current) {
|
|
2155
|
-
observerRef.current.disconnect();
|
|
2156
|
-
}
|
|
2157
|
-
};
|
|
2158
|
-
}, [hasMore, isLoadingMore, loadMore]);
|
|
2159
|
-
if (isLoading) {
|
|
2160
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 space-y-2", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2161
|
-
uiNextjs.Skeleton,
|
|
2162
|
-
{
|
|
2163
|
-
className: "h-24 w-full animate-pulse",
|
|
2164
|
-
style: { animationDelay: `${i * 100}ms` }
|
|
2165
|
-
}
|
|
2166
|
-
) }, i)) });
|
|
2167
|
-
}
|
|
2168
|
-
if (!tickets || tickets.length === 0) {
|
|
2169
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center animate-in fade-in zoom-in-95 duration-300", children: [
|
|
2170
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-16 w-16 text-muted-foreground mb-4 animate-bounce" }),
|
|
2171
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No tickets yet" }),
|
|
2172
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: "Create your first support ticket to get help from our team" })
|
|
2173
|
-
] });
|
|
2174
|
-
}
|
|
2175
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.ScrollArea, { className: "h-full", viewportRef: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 space-y-2", children: [
|
|
2176
|
-
tickets.map((ticket, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2177
|
-
"div",
|
|
2178
|
-
{
|
|
2179
|
-
className: "animate-in fade-in slide-in-from-left-2 duration-300",
|
|
2180
|
-
style: { animationDelay: `${Math.min(index, 10) * 50}ms` },
|
|
2181
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2182
|
-
TicketCard,
|
|
2183
|
-
{
|
|
2184
|
-
ticket,
|
|
2185
|
-
isSelected: selectedTicket?.uuid === ticket.uuid,
|
|
2186
|
-
onClick: () => selectTicket(ticket)
|
|
2187
|
-
}
|
|
2188
|
-
)
|
|
2189
|
-
},
|
|
2190
|
-
ticket.uuid
|
|
2191
|
-
)),
|
|
2192
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: loadMoreRef, className: "h-2" }),
|
|
2193
|
-
isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
2194
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2195
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading more tickets..." })
|
|
2196
|
-
] }) }),
|
|
2197
|
-
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2198
|
-
uiNextjs.Button,
|
|
2199
|
-
{
|
|
2200
|
-
variant: "outline",
|
|
2201
|
-
size: "sm",
|
|
2202
|
-
onClick: loadMore,
|
|
2203
|
-
className: "text-xs",
|
|
2204
|
-
children: [
|
|
2205
|
-
"Load more (",
|
|
2206
|
-
totalCount > 0 ? `${tickets.length}/${totalCount}` : "",
|
|
2207
|
-
")"
|
|
2208
|
-
]
|
|
2209
|
-
}
|
|
2210
|
-
) }),
|
|
2211
|
-
!hasMore && tickets.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-4 text-sm text-muted-foreground", children: [
|
|
2212
|
-
"All ",
|
|
2213
|
-
totalCount,
|
|
2214
|
-
" tickets loaded"
|
|
2215
|
-
] })
|
|
2216
|
-
] }) });
|
|
2217
|
-
};
|
|
2218
|
-
var formatTime = (date) => {
|
|
2219
|
-
if (!date) return "";
|
|
2220
|
-
return new Date(date).toLocaleTimeString("en-US", {
|
|
2221
|
-
hour: "2-digit",
|
|
2222
|
-
minute: "2-digit"
|
|
2223
|
-
});
|
|
2224
|
-
};
|
|
2225
|
-
var formatDate = (date) => {
|
|
2226
|
-
if (!date) return "";
|
|
2227
|
-
return new Date(date).toLocaleDateString("en-US", {
|
|
2228
|
-
year: "numeric",
|
|
2229
|
-
month: "short",
|
|
2230
|
-
day: "numeric"
|
|
2231
|
-
});
|
|
2232
|
-
};
|
|
2233
|
-
var MessageBubble = ({ message, isFromUser, currentUser }) => {
|
|
2234
|
-
const sender = message.sender;
|
|
2235
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2236
|
-
"div",
|
|
2237
|
-
{
|
|
2238
|
-
className: `flex gap-3 ${isFromUser ? "justify-end" : "justify-start"}
|
|
2239
|
-
animate-in fade-in slide-in-from-bottom-2 duration-300`,
|
|
2240
|
-
children: [
|
|
2241
|
-
!isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Avatar, { className: "h-8 w-8 shrink-0", children: sender?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.AvatarImage, { src: sender.avatar, alt: sender.display_username || "Support" }) : /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.AvatarFallback, { className: "bg-primary text-primary-foreground", children: sender?.is_staff ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Headphones, { className: "h-4 w-4" }) : sender?.display_username?.charAt(0)?.toUpperCase() || sender?.initials || "S" }) }),
|
|
2242
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 flex-1 max-w-[80%] ${isFromUser ? "items-end" : "items-start"}`, children: [
|
|
2243
|
-
!isFromUser && sender && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-1", children: [
|
|
2244
|
-
sender.display_username || sender.email || "Support Team",
|
|
2245
|
-
sender.is_staff && " (Staff)"
|
|
2246
|
-
] }),
|
|
2247
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2248
|
-
uiNextjs.Card,
|
|
2249
|
-
{
|
|
2250
|
-
className: `${isFromUser ? "bg-primary text-primary-foreground" : "bg-muted"} transition-all duration-200 hover:shadow-md`,
|
|
2251
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm whitespace-pre-wrap break-words", children: message.text }) })
|
|
2252
|
-
}
|
|
2253
|
-
),
|
|
2254
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground px-1", children: formatTime(message.created_at) })
|
|
2255
|
-
] }),
|
|
2256
|
-
isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Avatar, { className: "h-8 w-8 shrink-0", children: currentUser?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.AvatarImage, { src: currentUser.avatar, alt: currentUser.display_username || currentUser.email || "You" }) : /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.AvatarFallback, { className: "bg-primary/10 text-primary font-semibold", children: currentUser?.display_username?.charAt(0)?.toUpperCase() || currentUser?.email?.charAt(0)?.toUpperCase() || currentUser?.initials || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "h-4 w-4" }) }) })
|
|
2257
|
-
]
|
|
2258
|
-
}
|
|
2259
|
-
);
|
|
2260
|
-
};
|
|
2261
|
-
var MessageList = () => {
|
|
2262
|
-
const { selectedTicket } = useSupportLayoutContext();
|
|
2263
|
-
const { user } = auth.useAuth();
|
|
2264
|
-
const {
|
|
2265
|
-
messages,
|
|
2266
|
-
isLoading,
|
|
2267
|
-
isLoadingMore,
|
|
2268
|
-
hasMore,
|
|
2269
|
-
totalCount,
|
|
2270
|
-
loadMore
|
|
2271
|
-
} = useInfiniteMessages(selectedTicket?.uuid || null);
|
|
2272
|
-
const scrollRef = React7.useRef(null);
|
|
2273
|
-
const scrollAreaRef = React7.useRef(null);
|
|
2274
|
-
const observerRef = React7.useRef(null);
|
|
2275
|
-
const loadMoreRef = React7.useRef(null);
|
|
2276
|
-
const firstRender = React7.useRef(true);
|
|
2277
|
-
React7.useEffect(() => {
|
|
2278
|
-
if (observerRef.current) {
|
|
2279
|
-
observerRef.current.disconnect();
|
|
2280
|
-
}
|
|
2281
|
-
observerRef.current = new IntersectionObserver(
|
|
2282
|
-
(entries) => {
|
|
2283
|
-
if (entries[0]?.isIntersecting && hasMore && !isLoadingMore) {
|
|
2284
|
-
loadMore();
|
|
2285
|
-
}
|
|
2286
|
-
},
|
|
2287
|
-
{ threshold: 0.1 }
|
|
2288
|
-
);
|
|
2289
|
-
if (loadMoreRef.current) {
|
|
2290
|
-
observerRef.current.observe(loadMoreRef.current);
|
|
2291
|
-
}
|
|
2292
|
-
return () => {
|
|
2293
|
-
if (observerRef.current) {
|
|
2294
|
-
observerRef.current.disconnect();
|
|
2295
|
-
}
|
|
2296
|
-
};
|
|
2297
|
-
}, [hasMore, isLoadingMore, loadMore]);
|
|
2298
|
-
React7.useEffect(() => {
|
|
2299
|
-
if (firstRender.current && messages.length > 0) {
|
|
2300
|
-
const scrollContainer = scrollAreaRef.current?.querySelector("[data-radix-scroll-area-viewport]");
|
|
2301
|
-
if (scrollContainer) {
|
|
2302
|
-
scrollContainer.scrollTop = scrollContainer.scrollHeight;
|
|
2303
|
-
}
|
|
2304
|
-
firstRender.current = false;
|
|
2305
|
-
}
|
|
2306
|
-
}, [messages]);
|
|
2307
|
-
const handleLoadMore = React7.useCallback(() => {
|
|
2308
|
-
const scrollContainer = scrollAreaRef.current?.querySelector("[data-radix-scroll-area-viewport]");
|
|
2309
|
-
const previousHeight = scrollContainer?.scrollHeight || 0;
|
|
2310
|
-
loadMore();
|
|
2311
|
-
setTimeout(() => {
|
|
2312
|
-
if (scrollContainer) {
|
|
2313
|
-
const newHeight = scrollContainer.scrollHeight;
|
|
2314
|
-
scrollContainer.scrollTop = newHeight - previousHeight;
|
|
2315
|
-
}
|
|
2316
|
-
}, 100);
|
|
2317
|
-
}, [loadMore]);
|
|
2318
|
-
if (!selectedTicket) {
|
|
2319
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center animate-in fade-in zoom-in-95 duration-300", children: [
|
|
2320
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-16 w-16 text-muted-foreground mb-4 animate-bounce" }),
|
|
2321
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No ticket selected" }),
|
|
2322
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: "Select a ticket from the list to view the conversation" })
|
|
2323
|
-
] });
|
|
2324
|
-
}
|
|
2325
|
-
if (isLoading) {
|
|
2326
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6 space-y-4", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2327
|
-
"div",
|
|
2328
|
-
{
|
|
2329
|
-
className: "flex gap-3 animate-pulse",
|
|
2330
|
-
style: { animationDelay: `${i * 100}ms` },
|
|
2331
|
-
children: [
|
|
2332
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-8 w-8 rounded-full" }),
|
|
2333
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Skeleton, { className: "h-16 flex-1 max-w-[70%]" })
|
|
2334
|
-
]
|
|
2335
|
-
},
|
|
2336
|
-
i
|
|
2337
|
-
)) });
|
|
2338
|
-
}
|
|
2339
|
-
if (!messages || messages.length === 0) {
|
|
2340
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center animate-in fade-in zoom-in-95 duration-300", children: [
|
|
2341
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-16 w-16 text-muted-foreground mb-4 animate-bounce" }),
|
|
2342
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold mb-2", children: "No messages yet" }),
|
|
2343
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: "Start the conversation by sending a message below" })
|
|
2344
|
-
] });
|
|
2345
|
-
}
|
|
2346
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.ScrollArea, { className: "h-full bg-muted/50", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-4", ref: scrollRef, children: [
|
|
2347
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: loadMoreRef, className: "h-2" }),
|
|
2348
|
-
isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
2349
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2350
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading older messages..." })
|
|
2351
|
-
] }) }),
|
|
2352
|
-
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2353
|
-
uiNextjs.Button,
|
|
2354
|
-
{
|
|
2355
|
-
variant: "outline",
|
|
2356
|
-
size: "sm",
|
|
2357
|
-
onClick: handleLoadMore,
|
|
2358
|
-
className: "text-xs",
|
|
2359
|
-
children: [
|
|
2360
|
-
"Load older messages (",
|
|
2361
|
-
totalCount > 0 ? `${messages.length}/${totalCount}` : "",
|
|
2362
|
-
")"
|
|
2363
|
-
]
|
|
2364
|
-
}
|
|
2365
|
-
) }),
|
|
2366
|
-
messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 my-4", children: [
|
|
2367
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2368
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(messages[0]?.created_at) }),
|
|
2369
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2370
|
-
] }),
|
|
2371
|
-
messages.map((message, index) => {
|
|
2372
|
-
const isFromUser = message.sender?.id && user?.id && String(message.sender.id) === String(user.id) || message.sender?.email && user?.email && message.sender.email === user.email || message.is_from_author && selectedTicket?.user && user?.id && String(selectedTicket.user) === String(user.id);
|
|
2373
|
-
const previousMessage = index > 0 ? messages[index - 1] : null;
|
|
2374
|
-
const showDateSeparator = previousMessage && new Date(previousMessage.created_at || "").toDateString() !== new Date(message.created_at || "").toDateString();
|
|
2375
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(React7__default.default.Fragment, { children: [
|
|
2376
|
-
showDateSeparator && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 my-4", children: [
|
|
2377
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2378
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(message.created_at) }),
|
|
2379
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2380
|
-
] }),
|
|
2381
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { animationDelay: `${Math.min(index, 10) * 50}ms` }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2382
|
-
MessageBubble,
|
|
2383
|
-
{
|
|
2384
|
-
message,
|
|
2385
|
-
isFromUser: !!isFromUser,
|
|
2386
|
-
currentUser: user
|
|
2387
|
-
}
|
|
2388
|
-
) })
|
|
2389
|
-
] }, message.uuid);
|
|
2390
|
-
})
|
|
2391
|
-
] }) });
|
|
2392
|
-
};
|
|
2393
|
-
var isDevelopment = process.env.NODE_ENV === "development";
|
|
2394
|
-
var showLogs = isDevelopment;
|
|
2395
|
-
var logger = consola.createConsola({
|
|
2396
|
-
level: showLogs ? 4 : 1
|
|
2397
|
-
}).withTag("ext-support");
|
|
2398
|
-
var supportLogger = logger;
|
|
2399
|
-
var MessageInput = () => {
|
|
2400
|
-
const { selectedTicket, sendMessage } = useSupportLayoutContext();
|
|
2401
|
-
const { toast } = uiNextjs.useToast();
|
|
2402
|
-
const [message, setMessage] = React7.useState("");
|
|
2403
|
-
const [isSending, setIsSending] = React7.useState(false);
|
|
2404
|
-
const handleSubmit = async (e) => {
|
|
2405
|
-
e.preventDefault();
|
|
2406
|
-
if (!message.trim() || !selectedTicket) return;
|
|
2407
|
-
setIsSending(true);
|
|
2408
|
-
try {
|
|
2409
|
-
await sendMessage(message.trim());
|
|
2410
|
-
setMessage("");
|
|
2411
|
-
toast({
|
|
2412
|
-
title: "Success",
|
|
2413
|
-
description: "Message sent successfully"
|
|
2414
|
-
});
|
|
2415
|
-
} catch (error) {
|
|
2416
|
-
supportLogger.error("Failed to send message:", error);
|
|
2417
|
-
toast({
|
|
2418
|
-
title: "Error",
|
|
2419
|
-
description: "Failed to send message",
|
|
2420
|
-
variant: "destructive"
|
|
2421
|
-
});
|
|
2422
|
-
} finally {
|
|
2423
|
-
setIsSending(false);
|
|
2424
|
-
}
|
|
2425
|
-
};
|
|
2426
|
-
const handleKeyDown = (e) => {
|
|
2427
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
2428
|
-
e.preventDefault();
|
|
2429
|
-
handleSubmit(e);
|
|
2430
|
-
}
|
|
2431
|
-
};
|
|
2432
|
-
if (!selectedTicket) {
|
|
2433
|
-
return null;
|
|
2434
|
-
}
|
|
2435
|
-
const canSendMessage = selectedTicket.status !== "closed";
|
|
2436
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "p-4 border-t bg-background/50 backdrop-blur-sm flex-shrink-0", children: [
|
|
2437
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
2438
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2439
|
-
uiNextjs.Textarea,
|
|
2440
|
-
{
|
|
2441
|
-
value: message,
|
|
2442
|
-
onChange: (e) => setMessage(e.target.value),
|
|
2443
|
-
onKeyDown: handleKeyDown,
|
|
2444
|
-
placeholder: canSendMessage ? "Type your message... (Shift+Enter for new line)" : "This ticket is closed",
|
|
2445
|
-
className: "min-h-[60px] max-h-[200px] transition-all duration-200 \n focus:ring-2 focus:ring-primary/20",
|
|
2446
|
-
disabled: !canSendMessage || isSending
|
|
2447
|
-
}
|
|
2448
|
-
),
|
|
2449
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2450
|
-
uiNextjs.Button,
|
|
2451
|
-
{
|
|
2452
|
-
type: "submit",
|
|
2453
|
-
size: "icon",
|
|
2454
|
-
disabled: !message.trim() || !canSendMessage || isSending,
|
|
2455
|
-
className: "shrink-0 transition-all duration-200 \n hover:scale-110 active:scale-95 disabled:scale-100",
|
|
2456
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-4 w-4" })
|
|
2457
|
-
}
|
|
2458
|
-
)
|
|
2459
|
-
] }),
|
|
2460
|
-
!canSendMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-2 animate-in fade-in slide-in-from-top-1 duration-200", children: "This ticket is closed. You cannot send new messages." })
|
|
2461
|
-
] });
|
|
2462
|
-
};
|
|
2463
|
-
var createTicketSchema = zod.z.object({
|
|
2464
|
-
subject: zod.z.string().min(1, "Subject is required").max(200, "Subject too long"),
|
|
2465
|
-
message: zod.z.string().min(1, "Message is required").max(5e3, "Message too long")
|
|
2466
|
-
});
|
|
2467
|
-
var CreateTicketDialog = () => {
|
|
2468
|
-
const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
|
|
2469
|
-
const { toast } = uiNextjs.useToast();
|
|
2470
|
-
const [isSubmitting, setIsSubmitting] = React7__default.default.useState(false);
|
|
2471
|
-
const form = reactHookForm.useForm({
|
|
2472
|
-
resolver: zod$1.zodResolver(createTicketSchema),
|
|
2473
|
-
defaultValues: {
|
|
2474
|
-
subject: "",
|
|
2475
|
-
message: ""
|
|
2476
|
-
}
|
|
2477
|
-
});
|
|
2478
|
-
const onSubmit = async (data) => {
|
|
2479
|
-
setIsSubmitting(true);
|
|
2480
|
-
try {
|
|
2481
|
-
await createTicket(data);
|
|
2482
|
-
form.reset();
|
|
2483
|
-
toast({
|
|
2484
|
-
title: "Success",
|
|
2485
|
-
description: "Support ticket created successfully"
|
|
2486
|
-
});
|
|
2487
|
-
} catch (error) {
|
|
2488
|
-
supportLogger.error("Failed to create ticket:", error);
|
|
2489
|
-
toast({
|
|
2490
|
-
title: "Error",
|
|
2491
|
-
description: "Failed to create ticket. Please try again.",
|
|
2492
|
-
variant: "destructive"
|
|
2493
|
-
});
|
|
2494
|
-
} finally {
|
|
2495
|
-
setIsSubmitting(false);
|
|
2496
|
-
}
|
|
2497
|
-
};
|
|
2498
|
-
const handleClose = () => {
|
|
2499
|
-
form.reset();
|
|
2500
|
-
closeCreateDialog();
|
|
2501
|
-
};
|
|
2502
|
-
return /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Dialog, { open: uiState.isCreateDialogOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogContent, { className: "sm:max-w-[600px] animate-in fade-in slide-in-from-bottom-4 duration-300", children: [
|
|
2503
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogHeader, { children: [
|
|
2504
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.DialogTitle, { className: "flex items-center gap-2", children: [
|
|
2505
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-5 w-5" }),
|
|
2506
|
-
"Create Support Ticket"
|
|
2507
|
-
] }),
|
|
2508
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.DialogDescription, { children: "Describe your issue and we'll help you resolve it as quickly as possible." })
|
|
2509
|
-
] }),
|
|
2510
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-6", children: [
|
|
2511
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2512
|
-
uiNextjs.FormField,
|
|
2513
|
-
{
|
|
2514
|
-
control: form.control,
|
|
2515
|
-
name: "subject",
|
|
2516
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
2517
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Subject" }),
|
|
2518
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Input, { placeholder: "Brief description of your issue...", ...field }) }),
|
|
2519
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
2520
|
-
] })
|
|
2521
|
-
}
|
|
2522
|
-
),
|
|
2523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
-
uiNextjs.FormField,
|
|
2525
|
-
{
|
|
2526
|
-
control: form.control,
|
|
2527
|
-
name: "message",
|
|
2528
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.FormItem, { children: [
|
|
2529
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormLabel, { children: "Message" }),
|
|
2530
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2531
|
-
uiNextjs.Textarea,
|
|
2532
|
-
{
|
|
2533
|
-
placeholder: "Describe your issue in detail. Include any error messages, steps to reproduce, or relevant information...",
|
|
2534
|
-
className: "min-h-[120px]",
|
|
2535
|
-
...field
|
|
2536
|
-
}
|
|
2537
|
-
) }),
|
|
2538
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.FormMessage, {})
|
|
2539
|
-
] })
|
|
2540
|
-
}
|
|
2541
|
-
),
|
|
2542
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3 pt-4", children: [
|
|
2543
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2544
|
-
uiNextjs.Button,
|
|
2545
|
-
{
|
|
2546
|
-
type: "button",
|
|
2547
|
-
variant: "outline",
|
|
2548
|
-
onClick: handleClose,
|
|
2549
|
-
disabled: isSubmitting,
|
|
2550
|
-
children: "Cancel"
|
|
2551
|
-
}
|
|
2552
|
-
),
|
|
2553
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2554
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2555
|
-
"Creating..."
|
|
2556
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2557
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2558
|
-
"Create Ticket"
|
|
2559
|
-
] }) })
|
|
2560
|
-
] })
|
|
2561
|
-
] }) })
|
|
2562
|
-
] }) });
|
|
2563
|
-
};
|
|
2564
|
-
var SupportLayoutContent = () => {
|
|
2565
|
-
const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } = useSupportLayoutContext();
|
|
2566
|
-
const [isMobile, setIsMobile] = React7__default.default.useState(false);
|
|
2567
|
-
React7__default.default.useEffect(() => {
|
|
2568
|
-
const checkMobile = () => setIsMobile(window.innerWidth <= 768);
|
|
2569
|
-
checkMobile();
|
|
2570
|
-
window.addEventListener("resize", checkMobile);
|
|
2571
|
-
return () => window.removeEventListener("resize", checkMobile);
|
|
2572
|
-
}, []);
|
|
2573
|
-
const unreadCount = getUnreadCount();
|
|
2574
|
-
if (isMobile) {
|
|
2575
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-screen flex flex-col overflow-hidden", children: [
|
|
2576
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b bg-background flex-shrink-0", children: [
|
|
2577
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2578
|
-
selectedTicket ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2579
|
-
uiNextjs.Button,
|
|
2580
|
-
{
|
|
2581
|
-
variant: "ghost",
|
|
2582
|
-
size: "sm",
|
|
2583
|
-
onClick: () => selectTicket(null),
|
|
2584
|
-
className: "p-1",
|
|
2585
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-5 w-5" })
|
|
2586
|
-
}
|
|
2587
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LifeBuoy, { className: "h-6 w-6 text-primary" }),
|
|
2588
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: selectedTicket ? selectedTicket.subject : "Support" }),
|
|
2589
|
-
unreadCount > 0 && !selectedTicket && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-5 w-5 bg-red-500 text-white text-xs rounded-full flex items-center justify-center", children: unreadCount })
|
|
2590
|
-
] }),
|
|
2591
|
-
!selectedTicket && /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: openCreateDialog, size: "sm", children: [
|
|
2592
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2593
|
-
"New Ticket"
|
|
2594
|
-
] })
|
|
2595
|
-
] }),
|
|
2596
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: selectedTicket ? (
|
|
2597
|
-
// Show messages when ticket is selected
|
|
2598
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col", children: [
|
|
2599
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(MessageList, {}) }),
|
|
2600
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(MessageInput, {}) })
|
|
2601
|
-
] })
|
|
2602
|
-
) : (
|
|
2603
|
-
// Show ticket list when no ticket is selected
|
|
2604
|
-
/* @__PURE__ */ jsxRuntime.jsx(TicketList, {})
|
|
2605
|
-
) }),
|
|
2606
|
-
/* @__PURE__ */ jsxRuntime.jsx(CreateTicketDialog, {})
|
|
2607
|
-
] });
|
|
2608
|
-
}
|
|
2609
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-screen flex flex-col overflow-hidden", children: [
|
|
2610
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-6 border-b bg-background flex-shrink-0", children: [
|
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2612
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.LifeBuoy, { className: "h-7 w-7 text-primary" }),
|
|
2613
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2614
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold", children: "Support Center" }),
|
|
2615
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Get help from our support team" })
|
|
2616
|
-
] }),
|
|
2617
|
-
unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-6 bg-red-500 text-white text-sm rounded-full flex items-center justify-center", children: unreadCount })
|
|
2618
|
-
] }),
|
|
2619
|
-
/* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.Button, { onClick: openCreateDialog, children: [
|
|
2620
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2621
|
-
"New Ticket"
|
|
2622
|
-
] })
|
|
2623
|
-
] }),
|
|
2624
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(uiNextjs.ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [
|
|
2625
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.ResizablePanel, { defaultSize: 35, minSize: 25, maxSize: 50, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full border-r overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(TicketList, {}) }) }),
|
|
2626
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.ResizableHandle, { withHandle: true, className: "hover:bg-accent transition-colors" }),
|
|
2627
|
-
/* @__PURE__ */ jsxRuntime.jsx(uiNextjs.ResizablePanel, { defaultSize: 65, minSize: 50, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [
|
|
2628
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(MessageList, {}) }),
|
|
2629
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(MessageInput, {}) })
|
|
2630
|
-
] }) })
|
|
2631
|
-
] }) }),
|
|
2632
|
-
/* @__PURE__ */ jsxRuntime.jsx(CreateTicketDialog, {})
|
|
2633
|
-
] });
|
|
2634
|
-
};
|
|
2635
|
-
var SupportLayout = () => {
|
|
2636
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-screen w-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(SupportProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(SupportLayoutProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(SupportLayoutContent, {}) }) }) });
|
|
2637
|
-
};
|
|
2638
|
-
|
|
2639
|
-
exports.API = API;
|
|
2640
|
-
exports.APIClient = APIClient;
|
|
2641
|
-
exports.APIError = APIError;
|
|
2642
|
-
exports.APILogger = APILogger;
|
|
2643
|
-
exports.CookieStorageAdapter = CookieStorageAdapter;
|
|
2644
|
-
exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
|
|
2645
|
-
exports.Enums = enums_exports;
|
|
2646
|
-
exports.ExtSupportSupportTypes = models_exports;
|
|
2647
|
-
exports.FetchAdapter = FetchAdapter;
|
|
2648
|
-
exports.Fetchers = fetchers_exports;
|
|
2649
|
-
exports.LocalStorageAdapter = LocalStorageAdapter;
|
|
2650
|
-
exports.MemoryStorageAdapter = MemoryStorageAdapter;
|
|
2651
|
-
exports.MessageCreateRequestSchema = MessageCreateRequestSchema;
|
|
2652
|
-
exports.MessageCreateSchema = MessageCreateSchema;
|
|
2653
|
-
exports.MessageRequestSchema = MessageRequestSchema;
|
|
2654
|
-
exports.MessageSchema = MessageSchema;
|
|
2655
|
-
exports.NetworkError = NetworkError;
|
|
2656
|
-
exports.PaginatedMessageListSchema = PaginatedMessageListSchema;
|
|
2657
|
-
exports.PaginatedTicketListSchema = PaginatedTicketListSchema;
|
|
2658
|
-
exports.PatchedMessageRequestSchema = PatchedMessageRequestSchema;
|
|
2659
|
-
exports.PatchedTicketRequestSchema = PatchedTicketRequestSchema;
|
|
2660
|
-
exports.REFRESH_TOKEN_KEY = REFRESH_TOKEN_KEY;
|
|
2661
|
-
exports.SUPPORT_LAYOUT_EVENTS = SUPPORT_LAYOUT_EVENTS;
|
|
2662
|
-
exports.Schemas = schemas_exports;
|
|
2663
|
-
exports.SenderSchema = SenderSchema;
|
|
2664
|
-
exports.SupportLayout = SupportLayout;
|
|
2665
|
-
exports.TOKEN_KEY = TOKEN_KEY;
|
|
2666
|
-
exports.TicketRequestSchema = TicketRequestSchema;
|
|
2667
|
-
exports.TicketSchema = TicketSchema;
|
|
2668
|
-
exports.apiSupport = apiSupport;
|
|
2669
|
-
exports.clearAPITokens = clearAPITokens;
|
|
2670
|
-
exports.closeCreateTicketDialog = closeCreateTicketDialog;
|
|
2671
|
-
exports.configureAPI = configureAPI;
|
|
2672
|
-
exports.createSupportTicketsCreate = createSupportTicketsCreate;
|
|
2673
|
-
exports.createSupportTicketsMessagesCreate = createSupportTicketsMessagesCreate;
|
|
2674
|
-
exports.deleteSupportTicketsDestroy = deleteSupportTicketsDestroy;
|
|
2675
|
-
exports.deleteSupportTicketsMessagesDestroy = deleteSupportTicketsMessagesDestroy;
|
|
2676
|
-
exports.dispatchValidationError = dispatchValidationError;
|
|
2677
|
-
exports.formatZodError = formatZodError;
|
|
2678
|
-
exports.getAPIInstance = getAPIInstance;
|
|
2679
|
-
exports.getSupportTicketsList = getSupportTicketsList;
|
|
2680
|
-
exports.getSupportTicketsMessagesList = getSupportTicketsMessagesList;
|
|
2681
|
-
exports.getSupportTicketsMessagesRetrieve = getSupportTicketsMessagesRetrieve;
|
|
2682
|
-
exports.getSupportTicketsRetrieve = getSupportTicketsRetrieve;
|
|
2683
|
-
exports.isAPIConfigured = isAPIConfigured;
|
|
2684
|
-
exports.onValidationError = onValidationError;
|
|
2685
|
-
exports.openCreateTicketDialog = openCreateTicketDialog;
|
|
2686
|
-
exports.partialUpdateSupportTicketsMessagesPartialUpdate = partialUpdateSupportTicketsMessagesPartialUpdate;
|
|
2687
|
-
exports.partialUpdateSupportTicketsPartialUpdate = partialUpdateSupportTicketsPartialUpdate;
|
|
2688
|
-
exports.reconfigureAPI = reconfigureAPI;
|
|
2689
|
-
exports.resetAPI = resetAPI;
|
|
2690
|
-
exports.shouldRetry = shouldRetry;
|
|
2691
|
-
exports.updateSupportTicketsMessagesUpdate = updateSupportTicketsMessagesUpdate;
|
|
2692
|
-
exports.updateSupportTicketsUpdate = updateSupportTicketsUpdate;
|
|
2693
|
-
exports.withRetry = withRetry;
|