@djangocfg/ext-support 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.cjs +3 -2
- package/dist/config.js +3 -2
- package/dist/hooks.cjs +53 -57
- package/dist/hooks.js +9 -13
- package/dist/index.cjs +53 -57
- package/dist/index.js +9 -13
- package/package.json +8 -7
- package/src/layouts/SupportLayout/SupportLayout.tsx +1 -1
- package/src/layouts/SupportLayout/components/CreateTicketDialog.tsx +1 -1
- package/src/layouts/SupportLayout/components/MessageInput.tsx +4 -10
- package/src/layouts/SupportLayout/components/MessageList.tsx +1 -1
- package/src/layouts/SupportLayout/components/TicketCard.tsx +2 -1
- package/src/layouts/SupportLayout/components/TicketList.tsx +1 -1
package/dist/config.cjs
CHANGED
|
@@ -27,7 +27,7 @@ var import_ext_base = require("@djangocfg/ext-base");
|
|
|
27
27
|
// package.json
|
|
28
28
|
var package_default = {
|
|
29
29
|
name: "@djangocfg/ext-support",
|
|
30
|
-
version: "1.0.
|
|
30
|
+
version: "1.0.9",
|
|
31
31
|
description: "Support ticket system extension for DjangoCFG",
|
|
32
32
|
keywords: [
|
|
33
33
|
"django",
|
|
@@ -88,7 +88,7 @@ var package_default = {
|
|
|
88
88
|
peerDependencies: {
|
|
89
89
|
"@djangocfg/api": "workspace:*",
|
|
90
90
|
"@djangocfg/ext-base": "workspace:*",
|
|
91
|
-
"@djangocfg/ui-
|
|
91
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
92
92
|
consola: "^3.4.2",
|
|
93
93
|
"lucide-react": "^0.545.0",
|
|
94
94
|
moment: "^2.30.1",
|
|
@@ -102,6 +102,7 @@ var package_default = {
|
|
|
102
102
|
devDependencies: {
|
|
103
103
|
"@djangocfg/api": "workspace:*",
|
|
104
104
|
"@djangocfg/ext-base": "workspace:*",
|
|
105
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
105
106
|
"@djangocfg/typescript-config": "workspace:*",
|
|
106
107
|
"@types/node": "^24.7.2",
|
|
107
108
|
"@types/react": "^19.0.0",
|
package/dist/config.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createExtensionConfig } from "@djangocfg/ext-base";
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@djangocfg/ext-support",
|
|
7
|
-
version: "1.0.
|
|
7
|
+
version: "1.0.9",
|
|
8
8
|
description: "Support ticket system extension for DjangoCFG",
|
|
9
9
|
keywords: [
|
|
10
10
|
"django",
|
|
@@ -65,7 +65,7 @@ var package_default = {
|
|
|
65
65
|
peerDependencies: {
|
|
66
66
|
"@djangocfg/api": "workspace:*",
|
|
67
67
|
"@djangocfg/ext-base": "workspace:*",
|
|
68
|
-
"@djangocfg/ui-
|
|
68
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
69
69
|
consola: "^3.4.2",
|
|
70
70
|
"lucide-react": "^0.545.0",
|
|
71
71
|
moment: "^2.30.1",
|
|
@@ -79,6 +79,7 @@ var package_default = {
|
|
|
79
79
|
devDependencies: {
|
|
80
80
|
"@djangocfg/api": "workspace:*",
|
|
81
81
|
"@djangocfg/ext-base": "workspace:*",
|
|
82
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
82
83
|
"@djangocfg/typescript-config": "workspace:*",
|
|
83
84
|
"@types/node": "^24.7.2",
|
|
84
85
|
"@types/react": "^19.0.0",
|
package/dist/hooks.cjs
CHANGED
|
@@ -6,12 +6,14 @@ var zod = require('zod');
|
|
|
6
6
|
var api = require('@djangocfg/ext-base/api');
|
|
7
7
|
var lucideReact = require('lucide-react');
|
|
8
8
|
var React7 = require('react');
|
|
9
|
-
var
|
|
9
|
+
var uiCore = require('@djangocfg/ui-core');
|
|
10
10
|
var useSWR = require('swr');
|
|
11
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
12
|
var moment2 = require('moment');
|
|
13
|
+
var lib = require('@djangocfg/ui-core/lib');
|
|
13
14
|
var auth = require('@djangocfg/api/auth');
|
|
14
15
|
var useSWRInfinite = require('swr/infinite');
|
|
16
|
+
var hooks = require('@djangocfg/ui-core/hooks');
|
|
15
17
|
var reactHookForm = require('react-hook-form');
|
|
16
18
|
var zod$1 = require('@hookform/resolvers/zod');
|
|
17
19
|
var extBase = require('@djangocfg/ext-base');
|
|
@@ -1815,20 +1817,20 @@ var formatRelativeTime = (date) => {
|
|
|
1815
1817
|
};
|
|
1816
1818
|
var TicketCard = ({ ticket, isSelected, onClick }) => {
|
|
1817
1819
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1818
|
-
|
|
1820
|
+
uiCore.Card,
|
|
1819
1821
|
{
|
|
1820
|
-
className:
|
|
1822
|
+
className: lib.cn(
|
|
1821
1823
|
"cursor-pointer transition-all duration-200 ease-out",
|
|
1822
1824
|
"hover:bg-accent/50 hover:shadow-md hover:scale-[1.02]",
|
|
1823
1825
|
"active:scale-[0.98]",
|
|
1824
1826
|
isSelected && "bg-accent border-primary shadow-sm"
|
|
1825
1827
|
),
|
|
1826
1828
|
onClick,
|
|
1827
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1829
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardContent, { className: "p-4", children: [
|
|
1828
1830
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-2", children: [
|
|
1829
1831
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-sm line-clamp-2 flex-1", children: ticket.subject }),
|
|
1830
1832
|
(ticket.unanswered_messages_count || 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1831
|
-
|
|
1833
|
+
uiCore.Badge,
|
|
1832
1834
|
{
|
|
1833
1835
|
variant: "destructive",
|
|
1834
1836
|
className: "ml-2 shrink-0 animate-pulse",
|
|
@@ -1837,7 +1839,7 @@ var TicketCard = ({ ticket, isSelected, onClick }) => {
|
|
|
1837
1839
|
)
|
|
1838
1840
|
] }),
|
|
1839
1841
|
/* @__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: [
|
|
1840
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1842
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: getStatusBadgeVariant(ticket.status || "open"), className: "text-xs", children: ticket.status || "open" }),
|
|
1841
1843
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1842
1844
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3 w-3" }),
|
|
1843
1845
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatRelativeTime(ticket.created_at) })
|
|
@@ -2157,7 +2159,7 @@ var TicketList = () => {
|
|
|
2157
2159
|
}, [hasMore, isLoadingMore, loadMore]);
|
|
2158
2160
|
if (isLoading) {
|
|
2159
2161
|
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(
|
|
2160
|
-
|
|
2162
|
+
uiCore.Skeleton,
|
|
2161
2163
|
{
|
|
2162
2164
|
className: "h-24 w-full animate-pulse",
|
|
2163
2165
|
style: { animationDelay: `${i * 100}ms` }
|
|
@@ -2171,7 +2173,7 @@ var TicketList = () => {
|
|
|
2171
2173
|
/* @__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" })
|
|
2172
2174
|
] });
|
|
2173
2175
|
}
|
|
2174
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2176
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ScrollArea, { className: "h-full", viewportRef: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 space-y-2", children: [
|
|
2175
2177
|
tickets.map((ticket, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2176
2178
|
"div",
|
|
2177
2179
|
{
|
|
@@ -2194,7 +2196,7 @@ var TicketList = () => {
|
|
|
2194
2196
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading more tickets..." })
|
|
2195
2197
|
] }) }),
|
|
2196
2198
|
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2197
|
-
|
|
2199
|
+
uiCore.Button,
|
|
2198
2200
|
{
|
|
2199
2201
|
variant: "outline",
|
|
2200
2202
|
size: "sm",
|
|
@@ -2232,22 +2234,22 @@ var MessageBubble = ({ message, isFromUser, currentUser }) => {
|
|
|
2232
2234
|
className: `flex gap-3 ${isFromUser ? "justify-end" : "justify-start"}
|
|
2233
2235
|
animate-in fade-in slide-in-from-bottom-2 duration-300`,
|
|
2234
2236
|
children: [
|
|
2235
|
-
!isFromUser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2237
|
+
!isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Avatar, { className: "h-8 w-8 shrink-0", children: sender?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarImage, { src: sender.avatar, alt: sender.display_username || "Support" }) : /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarFallback, { className: "bg-primary text-primary-foreground", children: sender?.is_staff ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Headphones, { className: "h-4 w-4" }) : senderInitial }) }),
|
|
2236
2238
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 flex-1 max-w-[80%] ${isFromUser ? "items-end" : "items-start"}`, children: [
|
|
2237
2239
|
!isFromUser && sender && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-1", children: [
|
|
2238
2240
|
sender.display_username || sender.email || "Support Team",
|
|
2239
2241
|
sender.is_staff && " (Staff)"
|
|
2240
2242
|
] }),
|
|
2241
2243
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2242
|
-
|
|
2244
|
+
uiCore.Card,
|
|
2243
2245
|
{
|
|
2244
2246
|
className: `${isFromUser ? "bg-primary text-primary-foreground" : "bg-muted"} transition-all duration-200 hover:shadow-md`,
|
|
2245
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2247
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm whitespace-pre-wrap break-words", children: message.text }) })
|
|
2246
2248
|
}
|
|
2247
2249
|
),
|
|
2248
2250
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground px-1", children: formatTime(message.created_at) })
|
|
2249
2251
|
] }),
|
|
2250
|
-
isFromUser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2252
|
+
isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Avatar, { className: "h-8 w-8 shrink-0", children: currentUser?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarImage, { src: currentUser.avatar, alt: currentUser.display_username || currentUser.email || "You" }) : /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarFallback, { className: "bg-primary/10 text-primary font-semibold", children: userInitial || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "h-4 w-4" }) }) })
|
|
2251
2253
|
]
|
|
2252
2254
|
}
|
|
2253
2255
|
);
|
|
@@ -2323,8 +2325,8 @@ var MessageList = () => {
|
|
|
2323
2325
|
className: "flex gap-3 animate-pulse",
|
|
2324
2326
|
style: { animationDelay: `${i * 100}ms` },
|
|
2325
2327
|
children: [
|
|
2326
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2327
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2328
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-8 w-8 rounded-full" }),
|
|
2329
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-16 flex-1 max-w-[70%]" })
|
|
2328
2330
|
]
|
|
2329
2331
|
},
|
|
2330
2332
|
i
|
|
@@ -2337,14 +2339,14 @@ var MessageList = () => {
|
|
|
2337
2339
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: "Start the conversation by sending a message below" })
|
|
2338
2340
|
] });
|
|
2339
2341
|
}
|
|
2340
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2342
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ScrollArea, { className: "h-full bg-muted/50", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-4", ref: scrollRef, children: [
|
|
2341
2343
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: loadMoreRef, className: "h-2" }),
|
|
2342
2344
|
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: [
|
|
2343
2345
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2344
2346
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading older messages..." })
|
|
2345
2347
|
] }) }),
|
|
2346
2348
|
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2347
|
-
|
|
2349
|
+
uiCore.Button,
|
|
2348
2350
|
{
|
|
2349
2351
|
variant: "outline",
|
|
2350
2352
|
size: "sm",
|
|
@@ -2392,7 +2394,7 @@ var logger = consola.createConsola({
|
|
|
2392
2394
|
var supportLogger = logger;
|
|
2393
2395
|
var MessageInput = () => {
|
|
2394
2396
|
const { selectedTicket, sendMessage } = useSupportLayoutContext();
|
|
2395
|
-
const { toast } =
|
|
2397
|
+
const { toast } = hooks.useToast();
|
|
2396
2398
|
const [message, setMessage] = React7.useState("");
|
|
2397
2399
|
const [isSending, setIsSending] = React7.useState(false);
|
|
2398
2400
|
const handleSubmit = async (e) => {
|
|
@@ -2402,17 +2404,10 @@ var MessageInput = () => {
|
|
|
2402
2404
|
try {
|
|
2403
2405
|
await sendMessage(message.trim());
|
|
2404
2406
|
setMessage("");
|
|
2405
|
-
toast(
|
|
2406
|
-
title: "Success",
|
|
2407
|
-
description: "Message sent successfully"
|
|
2408
|
-
});
|
|
2407
|
+
toast.success("Message sent successfully");
|
|
2409
2408
|
} catch (error) {
|
|
2410
2409
|
supportLogger.error("Failed to send message:", error);
|
|
2411
|
-
toast(
|
|
2412
|
-
title: "Error",
|
|
2413
|
-
description: "Failed to send message",
|
|
2414
|
-
variant: "destructive"
|
|
2415
|
-
});
|
|
2410
|
+
toast.error("Failed to send message");
|
|
2416
2411
|
} finally {
|
|
2417
2412
|
setIsSending(false);
|
|
2418
2413
|
}
|
|
@@ -2430,7 +2425,7 @@ var MessageInput = () => {
|
|
|
2430
2425
|
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "p-4 border-t bg-background/50 backdrop-blur-sm flex-shrink-0", children: [
|
|
2431
2426
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
2432
2427
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2433
|
-
|
|
2428
|
+
uiCore.Textarea,
|
|
2434
2429
|
{
|
|
2435
2430
|
value: message,
|
|
2436
2431
|
onChange: (e) => setMessage(e.target.value),
|
|
@@ -2441,7 +2436,7 @@ var MessageInput = () => {
|
|
|
2441
2436
|
}
|
|
2442
2437
|
),
|
|
2443
2438
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2444
|
-
|
|
2439
|
+
uiCore.Button,
|
|
2445
2440
|
{
|
|
2446
2441
|
type: "submit",
|
|
2447
2442
|
size: "icon",
|
|
@@ -2460,7 +2455,7 @@ var createTicketSchema = zod.z.object({
|
|
|
2460
2455
|
});
|
|
2461
2456
|
var CreateTicketDialog = () => {
|
|
2462
2457
|
const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
|
|
2463
|
-
const { toast } =
|
|
2458
|
+
const { toast } = uiCore.useToast();
|
|
2464
2459
|
const [isSubmitting, setIsSubmitting] = React7__default.default.useState(false);
|
|
2465
2460
|
const form = reactHookForm.useForm({
|
|
2466
2461
|
resolver: zod$1.zodResolver(createTicketSchema),
|
|
@@ -2493,49 +2488,49 @@ var CreateTicketDialog = () => {
|
|
|
2493
2488
|
form.reset();
|
|
2494
2489
|
closeCreateDialog();
|
|
2495
2490
|
};
|
|
2496
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2497
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2491
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.Dialog, { open: uiState.isCreateDialogOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogContent, { className: "sm:max-w-[600px] animate-in fade-in slide-in-from-bottom-4 duration-300", children: [
|
|
2492
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogHeader, { children: [
|
|
2493
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogTitle, { className: "flex items-center gap-2", children: [
|
|
2499
2494
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-5 w-5" }),
|
|
2500
2495
|
"Create Support Ticket"
|
|
2501
2496
|
] }),
|
|
2502
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.DialogDescription, { children: "Describe your issue and we'll help you resolve it as quickly as possible." })
|
|
2503
2498
|
] }),
|
|
2504
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2499
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-6", children: [
|
|
2505
2500
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2506
|
-
|
|
2501
|
+
uiCore.FormField,
|
|
2507
2502
|
{
|
|
2508
2503
|
control: form.control,
|
|
2509
2504
|
name: "subject",
|
|
2510
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2511
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2512
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2513
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2505
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2506
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Subject" }),
|
|
2507
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Input, { placeholder: "Brief description of your issue...", ...field }) }),
|
|
2508
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2514
2509
|
] })
|
|
2515
2510
|
}
|
|
2516
2511
|
),
|
|
2517
2512
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2518
|
-
|
|
2513
|
+
uiCore.FormField,
|
|
2519
2514
|
{
|
|
2520
2515
|
control: form.control,
|
|
2521
2516
|
name: "message",
|
|
2522
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2525
|
-
|
|
2517
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2518
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Message" }),
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2520
|
+
uiCore.Textarea,
|
|
2526
2521
|
{
|
|
2527
2522
|
placeholder: "Describe your issue in detail. Include any error messages, steps to reproduce, or relevant information...",
|
|
2528
2523
|
className: "min-h-[120px]",
|
|
2529
2524
|
...field
|
|
2530
2525
|
}
|
|
2531
2526
|
) }),
|
|
2532
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2527
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2533
2528
|
] })
|
|
2534
2529
|
}
|
|
2535
2530
|
),
|
|
2536
2531
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3 pt-4", children: [
|
|
2537
2532
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2538
|
-
|
|
2533
|
+
uiCore.Button,
|
|
2539
2534
|
{
|
|
2540
2535
|
type: "button",
|
|
2541
2536
|
variant: "outline",
|
|
@@ -2544,7 +2539,7 @@ var CreateTicketDialog = () => {
|
|
|
2544
2539
|
children: "Cancel"
|
|
2545
2540
|
}
|
|
2546
2541
|
),
|
|
2547
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2542
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2548
2543
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2549
2544
|
"Creating..."
|
|
2550
2545
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2570,7 +2565,7 @@ var SupportLayoutContent = () => {
|
|
|
2570
2565
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b bg-background flex-shrink-0", children: [
|
|
2571
2566
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2572
2567
|
selectedTicket ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2573
|
-
|
|
2568
|
+
uiCore.Button,
|
|
2574
2569
|
{
|
|
2575
2570
|
variant: "ghost",
|
|
2576
2571
|
size: "sm",
|
|
@@ -2582,7 +2577,7 @@ var SupportLayoutContent = () => {
|
|
|
2582
2577
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: selectedTicket ? selectedTicket.subject : "Support" }),
|
|
2583
2578
|
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 })
|
|
2584
2579
|
] }),
|
|
2585
|
-
!selectedTicket && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2580
|
+
!selectedTicket && /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: openCreateDialog, size: "sm", children: [
|
|
2586
2581
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2587
2582
|
"New Ticket"
|
|
2588
2583
|
] })
|
|
@@ -2610,15 +2605,15 @@ var SupportLayoutContent = () => {
|
|
|
2610
2605
|
] }),
|
|
2611
2606
|
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 })
|
|
2612
2607
|
] }),
|
|
2613
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2608
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: openCreateDialog, children: [
|
|
2614
2609
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2615
2610
|
"New Ticket"
|
|
2616
2611
|
] })
|
|
2617
2612
|
] }),
|
|
2618
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2619
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2620
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2621
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2613
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [
|
|
2614
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizablePanel, { defaultSize: 35, minSize: 25, maxSize: 50, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full border-r overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(TicketList, {}) }) }),
|
|
2615
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizableHandle, { withHandle: true, className: "hover:bg-accent transition-colors" }),
|
|
2616
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizablePanel, { defaultSize: 65, minSize: 50, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [
|
|
2622
2617
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(MessageList, {}) }),
|
|
2623
2618
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(MessageInput, {}) })
|
|
2624
2619
|
] }) })
|
|
@@ -2633,7 +2628,7 @@ var SupportLayout = () => {
|
|
|
2633
2628
|
// package.json
|
|
2634
2629
|
var package_default = {
|
|
2635
2630
|
name: "@djangocfg/ext-support",
|
|
2636
|
-
version: "1.0.
|
|
2631
|
+
version: "1.0.9",
|
|
2637
2632
|
description: "Support ticket system extension for DjangoCFG",
|
|
2638
2633
|
keywords: [
|
|
2639
2634
|
"django",
|
|
@@ -2694,7 +2689,7 @@ var package_default = {
|
|
|
2694
2689
|
peerDependencies: {
|
|
2695
2690
|
"@djangocfg/api": "workspace:*",
|
|
2696
2691
|
"@djangocfg/ext-base": "workspace:*",
|
|
2697
|
-
"@djangocfg/ui-
|
|
2692
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2698
2693
|
consola: "^3.4.2",
|
|
2699
2694
|
"lucide-react": "^0.545.0",
|
|
2700
2695
|
moment: "^2.30.1",
|
|
@@ -2708,6 +2703,7 @@ var package_default = {
|
|
|
2708
2703
|
devDependencies: {
|
|
2709
2704
|
"@djangocfg/api": "workspace:*",
|
|
2710
2705
|
"@djangocfg/ext-base": "workspace:*",
|
|
2706
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2711
2707
|
"@djangocfg/typescript-config": "workspace:*",
|
|
2712
2708
|
"@types/node": "^24.7.2",
|
|
2713
2709
|
"@types/react": "^19.0.0",
|
package/dist/hooks.js
CHANGED
|
@@ -4,12 +4,14 @@ import { z } from 'zod';
|
|
|
4
4
|
import { createExtensionAPI } from '@djangocfg/ext-base/api';
|
|
5
5
|
import { Clock, MessageSquare, Loader2, Send, Plus, Headphones, User, ArrowLeft, LifeBuoy } from 'lucide-react';
|
|
6
6
|
import React7, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react';
|
|
7
|
-
import { Card,
|
|
7
|
+
import { Card, CardContent, Badge, Skeleton, ScrollArea, Button, Textarea, useToast as useToast$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Avatar, AvatarImage, AvatarFallback, ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@djangocfg/ui-core';
|
|
8
8
|
import useSWR, { useSWRConfig } from 'swr';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import moment2 from 'moment';
|
|
11
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
11
12
|
import { useAuth } from '@djangocfg/api/auth';
|
|
12
13
|
import useSWRInfinite from 'swr/infinite';
|
|
14
|
+
import { useToast } from '@djangocfg/ui-core/hooks';
|
|
13
15
|
import { useForm } from 'react-hook-form';
|
|
14
16
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
15
17
|
import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
@@ -2392,17 +2394,10 @@ var MessageInput = () => {
|
|
|
2392
2394
|
try {
|
|
2393
2395
|
await sendMessage(message.trim());
|
|
2394
2396
|
setMessage("");
|
|
2395
|
-
toast(
|
|
2396
|
-
title: "Success",
|
|
2397
|
-
description: "Message sent successfully"
|
|
2398
|
-
});
|
|
2397
|
+
toast.success("Message sent successfully");
|
|
2399
2398
|
} catch (error) {
|
|
2400
2399
|
supportLogger.error("Failed to send message:", error);
|
|
2401
|
-
toast(
|
|
2402
|
-
title: "Error",
|
|
2403
|
-
description: "Failed to send message",
|
|
2404
|
-
variant: "destructive"
|
|
2405
|
-
});
|
|
2400
|
+
toast.error("Failed to send message");
|
|
2406
2401
|
} finally {
|
|
2407
2402
|
setIsSending(false);
|
|
2408
2403
|
}
|
|
@@ -2450,7 +2445,7 @@ var createTicketSchema = z.object({
|
|
|
2450
2445
|
});
|
|
2451
2446
|
var CreateTicketDialog = () => {
|
|
2452
2447
|
const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
|
|
2453
|
-
const { toast } = useToast();
|
|
2448
|
+
const { toast } = useToast$1();
|
|
2454
2449
|
const [isSubmitting, setIsSubmitting] = React7.useState(false);
|
|
2455
2450
|
const form = useForm({
|
|
2456
2451
|
resolver: zodResolver(createTicketSchema),
|
|
@@ -2623,7 +2618,7 @@ var SupportLayout = () => {
|
|
|
2623
2618
|
// package.json
|
|
2624
2619
|
var package_default = {
|
|
2625
2620
|
name: "@djangocfg/ext-support",
|
|
2626
|
-
version: "1.0.
|
|
2621
|
+
version: "1.0.9",
|
|
2627
2622
|
description: "Support ticket system extension for DjangoCFG",
|
|
2628
2623
|
keywords: [
|
|
2629
2624
|
"django",
|
|
@@ -2684,7 +2679,7 @@ var package_default = {
|
|
|
2684
2679
|
peerDependencies: {
|
|
2685
2680
|
"@djangocfg/api": "workspace:*",
|
|
2686
2681
|
"@djangocfg/ext-base": "workspace:*",
|
|
2687
|
-
"@djangocfg/ui-
|
|
2682
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2688
2683
|
consola: "^3.4.2",
|
|
2689
2684
|
"lucide-react": "^0.545.0",
|
|
2690
2685
|
moment: "^2.30.1",
|
|
@@ -2698,6 +2693,7 @@ var package_default = {
|
|
|
2698
2693
|
devDependencies: {
|
|
2699
2694
|
"@djangocfg/api": "workspace:*",
|
|
2700
2695
|
"@djangocfg/ext-base": "workspace:*",
|
|
2696
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2701
2697
|
"@djangocfg/typescript-config": "workspace:*",
|
|
2702
2698
|
"@types/node": "^24.7.2",
|
|
2703
2699
|
"@types/react": "^19.0.0",
|
package/dist/index.cjs
CHANGED
|
@@ -6,12 +6,14 @@ var zod = require('zod');
|
|
|
6
6
|
var api = require('@djangocfg/ext-base/api');
|
|
7
7
|
var lucideReact = require('lucide-react');
|
|
8
8
|
var React7 = require('react');
|
|
9
|
-
var
|
|
9
|
+
var uiCore = require('@djangocfg/ui-core');
|
|
10
10
|
var useSWR = require('swr');
|
|
11
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
12
12
|
var moment2 = require('moment');
|
|
13
|
+
var lib = require('@djangocfg/ui-core/lib');
|
|
13
14
|
var auth = require('@djangocfg/api/auth');
|
|
14
15
|
var useSWRInfinite = require('swr/infinite');
|
|
16
|
+
var hooks = require('@djangocfg/ui-core/hooks');
|
|
15
17
|
var reactHookForm = require('react-hook-form');
|
|
16
18
|
var zod$1 = require('@hookform/resolvers/zod');
|
|
17
19
|
var extBase = require('@djangocfg/ext-base');
|
|
@@ -1815,20 +1817,20 @@ var formatRelativeTime = (date) => {
|
|
|
1815
1817
|
};
|
|
1816
1818
|
var TicketCard = ({ ticket, isSelected, onClick }) => {
|
|
1817
1819
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1818
|
-
|
|
1820
|
+
uiCore.Card,
|
|
1819
1821
|
{
|
|
1820
|
-
className:
|
|
1822
|
+
className: lib.cn(
|
|
1821
1823
|
"cursor-pointer transition-all duration-200 ease-out",
|
|
1822
1824
|
"hover:bg-accent/50 hover:shadow-md hover:scale-[1.02]",
|
|
1823
1825
|
"active:scale-[0.98]",
|
|
1824
1826
|
isSelected && "bg-accent border-primary shadow-sm"
|
|
1825
1827
|
),
|
|
1826
1828
|
onClick,
|
|
1827
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1829
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.CardContent, { className: "p-4", children: [
|
|
1828
1830
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between mb-2", children: [
|
|
1829
1831
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-sm line-clamp-2 flex-1", children: ticket.subject }),
|
|
1830
1832
|
(ticket.unanswered_messages_count || 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1831
|
-
|
|
1833
|
+
uiCore.Badge,
|
|
1832
1834
|
{
|
|
1833
1835
|
variant: "destructive",
|
|
1834
1836
|
className: "ml-2 shrink-0 animate-pulse",
|
|
@@ -1837,7 +1839,7 @@ var TicketCard = ({ ticket, isSelected, onClick }) => {
|
|
|
1837
1839
|
)
|
|
1838
1840
|
] }),
|
|
1839
1841
|
/* @__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: [
|
|
1840
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1842
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Badge, { variant: getStatusBadgeVariant(ticket.status || "open"), className: "text-xs", children: ticket.status || "open" }),
|
|
1841
1843
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1842
1844
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3 w-3" }),
|
|
1843
1845
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatRelativeTime(ticket.created_at) })
|
|
@@ -2157,7 +2159,7 @@ var TicketList = () => {
|
|
|
2157
2159
|
}, [hasMore, isLoadingMore, loadMore]);
|
|
2158
2160
|
if (isLoading) {
|
|
2159
2161
|
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(
|
|
2160
|
-
|
|
2162
|
+
uiCore.Skeleton,
|
|
2161
2163
|
{
|
|
2162
2164
|
className: "h-24 w-full animate-pulse",
|
|
2163
2165
|
style: { animationDelay: `${i * 100}ms` }
|
|
@@ -2171,7 +2173,7 @@ var TicketList = () => {
|
|
|
2171
2173
|
/* @__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" })
|
|
2172
2174
|
] });
|
|
2173
2175
|
}
|
|
2174
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2176
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ScrollArea, { className: "h-full", viewportRef: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 space-y-2", children: [
|
|
2175
2177
|
tickets.map((ticket, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2176
2178
|
"div",
|
|
2177
2179
|
{
|
|
@@ -2194,7 +2196,7 @@ var TicketList = () => {
|
|
|
2194
2196
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading more tickets..." })
|
|
2195
2197
|
] }) }),
|
|
2196
2198
|
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2197
|
-
|
|
2199
|
+
uiCore.Button,
|
|
2198
2200
|
{
|
|
2199
2201
|
variant: "outline",
|
|
2200
2202
|
size: "sm",
|
|
@@ -2232,22 +2234,22 @@ var MessageBubble = ({ message, isFromUser, currentUser }) => {
|
|
|
2232
2234
|
className: `flex gap-3 ${isFromUser ? "justify-end" : "justify-start"}
|
|
2233
2235
|
animate-in fade-in slide-in-from-bottom-2 duration-300`,
|
|
2234
2236
|
children: [
|
|
2235
|
-
!isFromUser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2237
|
+
!isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Avatar, { className: "h-8 w-8 shrink-0", children: sender?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarImage, { src: sender.avatar, alt: sender.display_username || "Support" }) : /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarFallback, { className: "bg-primary text-primary-foreground", children: sender?.is_staff ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Headphones, { className: "h-4 w-4" }) : senderInitial }) }),
|
|
2236
2238
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 flex-1 max-w-[80%] ${isFromUser ? "items-end" : "items-start"}`, children: [
|
|
2237
2239
|
!isFromUser && sender && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-1", children: [
|
|
2238
2240
|
sender.display_username || sender.email || "Support Team",
|
|
2239
2241
|
sender.is_staff && " (Staff)"
|
|
2240
2242
|
] }),
|
|
2241
2243
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2242
|
-
|
|
2244
|
+
uiCore.Card,
|
|
2243
2245
|
{
|
|
2244
2246
|
className: `${isFromUser ? "bg-primary text-primary-foreground" : "bg-muted"} transition-all duration-200 hover:shadow-md`,
|
|
2245
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2247
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm whitespace-pre-wrap break-words", children: message.text }) })
|
|
2246
2248
|
}
|
|
2247
2249
|
),
|
|
2248
2250
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground px-1", children: formatTime(message.created_at) })
|
|
2249
2251
|
] }),
|
|
2250
|
-
isFromUser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2252
|
+
isFromUser && /* @__PURE__ */ jsxRuntime.jsx(uiCore.Avatar, { className: "h-8 w-8 shrink-0", children: currentUser?.avatar ? /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarImage, { src: currentUser.avatar, alt: currentUser.display_username || currentUser.email || "You" }) : /* @__PURE__ */ jsxRuntime.jsx(uiCore.AvatarFallback, { className: "bg-primary/10 text-primary font-semibold", children: userInitial || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "h-4 w-4" }) }) })
|
|
2251
2253
|
]
|
|
2252
2254
|
}
|
|
2253
2255
|
);
|
|
@@ -2323,8 +2325,8 @@ var MessageList = () => {
|
|
|
2323
2325
|
className: "flex gap-3 animate-pulse",
|
|
2324
2326
|
style: { animationDelay: `${i * 100}ms` },
|
|
2325
2327
|
children: [
|
|
2326
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2327
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2328
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-8 w-8 rounded-full" }),
|
|
2329
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Skeleton, { className: "h-16 flex-1 max-w-[70%]" })
|
|
2328
2330
|
]
|
|
2329
2331
|
},
|
|
2330
2332
|
i
|
|
@@ -2337,14 +2339,14 @@ var MessageList = () => {
|
|
|
2337
2339
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: "Start the conversation by sending a message below" })
|
|
2338
2340
|
] });
|
|
2339
2341
|
}
|
|
2340
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2342
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.ScrollArea, { className: "h-full bg-muted/50", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-4", ref: scrollRef, children: [
|
|
2341
2343
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: loadMoreRef, className: "h-2" }),
|
|
2342
2344
|
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: [
|
|
2343
2345
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2344
2346
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Loading older messages..." })
|
|
2345
2347
|
] }) }),
|
|
2346
2348
|
hasMore && !isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2347
|
-
|
|
2349
|
+
uiCore.Button,
|
|
2348
2350
|
{
|
|
2349
2351
|
variant: "outline",
|
|
2350
2352
|
size: "sm",
|
|
@@ -2392,7 +2394,7 @@ var logger = consola.createConsola({
|
|
|
2392
2394
|
var supportLogger = logger;
|
|
2393
2395
|
var MessageInput = () => {
|
|
2394
2396
|
const { selectedTicket, sendMessage } = useSupportLayoutContext();
|
|
2395
|
-
const { toast } =
|
|
2397
|
+
const { toast } = hooks.useToast();
|
|
2396
2398
|
const [message, setMessage] = React7.useState("");
|
|
2397
2399
|
const [isSending, setIsSending] = React7.useState(false);
|
|
2398
2400
|
const handleSubmit = async (e) => {
|
|
@@ -2402,17 +2404,10 @@ var MessageInput = () => {
|
|
|
2402
2404
|
try {
|
|
2403
2405
|
await sendMessage(message.trim());
|
|
2404
2406
|
setMessage("");
|
|
2405
|
-
toast(
|
|
2406
|
-
title: "Success",
|
|
2407
|
-
description: "Message sent successfully"
|
|
2408
|
-
});
|
|
2407
|
+
toast.success("Message sent successfully");
|
|
2409
2408
|
} catch (error) {
|
|
2410
2409
|
supportLogger.error("Failed to send message:", error);
|
|
2411
|
-
toast(
|
|
2412
|
-
title: "Error",
|
|
2413
|
-
description: "Failed to send message",
|
|
2414
|
-
variant: "destructive"
|
|
2415
|
-
});
|
|
2410
|
+
toast.error("Failed to send message");
|
|
2416
2411
|
} finally {
|
|
2417
2412
|
setIsSending(false);
|
|
2418
2413
|
}
|
|
@@ -2430,7 +2425,7 @@ var MessageInput = () => {
|
|
|
2430
2425
|
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "p-4 border-t bg-background/50 backdrop-blur-sm flex-shrink-0", children: [
|
|
2431
2426
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
2432
2427
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2433
|
-
|
|
2428
|
+
uiCore.Textarea,
|
|
2434
2429
|
{
|
|
2435
2430
|
value: message,
|
|
2436
2431
|
onChange: (e) => setMessage(e.target.value),
|
|
@@ -2441,7 +2436,7 @@ var MessageInput = () => {
|
|
|
2441
2436
|
}
|
|
2442
2437
|
),
|
|
2443
2438
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2444
|
-
|
|
2439
|
+
uiCore.Button,
|
|
2445
2440
|
{
|
|
2446
2441
|
type: "submit",
|
|
2447
2442
|
size: "icon",
|
|
@@ -2460,7 +2455,7 @@ var createTicketSchema = zod.z.object({
|
|
|
2460
2455
|
});
|
|
2461
2456
|
var CreateTicketDialog = () => {
|
|
2462
2457
|
const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
|
|
2463
|
-
const { toast } =
|
|
2458
|
+
const { toast } = uiCore.useToast();
|
|
2464
2459
|
const [isSubmitting, setIsSubmitting] = React7__default.default.useState(false);
|
|
2465
2460
|
const form = reactHookForm.useForm({
|
|
2466
2461
|
resolver: zod$1.zodResolver(createTicketSchema),
|
|
@@ -2493,49 +2488,49 @@ var CreateTicketDialog = () => {
|
|
|
2493
2488
|
form.reset();
|
|
2494
2489
|
closeCreateDialog();
|
|
2495
2490
|
};
|
|
2496
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2497
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2498
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2491
|
+
return /* @__PURE__ */ jsxRuntime.jsx(uiCore.Dialog, { open: uiState.isCreateDialogOpen, onOpenChange: (open) => !open && handleClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogContent, { className: "sm:max-w-[600px] animate-in fade-in slide-in-from-bottom-4 duration-300", children: [
|
|
2492
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogHeader, { children: [
|
|
2493
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.DialogTitle, { className: "flex items-center gap-2", children: [
|
|
2499
2494
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-5 w-5" }),
|
|
2500
2495
|
"Create Support Ticket"
|
|
2501
2496
|
] }),
|
|
2502
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.DialogDescription, { children: "Describe your issue and we'll help you resolve it as quickly as possible." })
|
|
2503
2498
|
] }),
|
|
2504
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2499
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-6", children: [
|
|
2505
2500
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2506
|
-
|
|
2501
|
+
uiCore.FormField,
|
|
2507
2502
|
{
|
|
2508
2503
|
control: form.control,
|
|
2509
2504
|
name: "subject",
|
|
2510
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2511
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2512
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2513
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2505
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2506
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Subject" }),
|
|
2507
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(uiCore.Input, { placeholder: "Brief description of your issue...", ...field }) }),
|
|
2508
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2514
2509
|
] })
|
|
2515
2510
|
}
|
|
2516
2511
|
),
|
|
2517
2512
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2518
|
-
|
|
2513
|
+
uiCore.FormField,
|
|
2519
2514
|
{
|
|
2520
2515
|
control: form.control,
|
|
2521
2516
|
name: "message",
|
|
2522
|
-
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2523
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2525
|
-
|
|
2517
|
+
render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(uiCore.FormItem, { children: [
|
|
2518
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormLabel, { children: "Message" }),
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2520
|
+
uiCore.Textarea,
|
|
2526
2521
|
{
|
|
2527
2522
|
placeholder: "Describe your issue in detail. Include any error messages, steps to reproduce, or relevant information...",
|
|
2528
2523
|
className: "min-h-[120px]",
|
|
2529
2524
|
...field
|
|
2530
2525
|
}
|
|
2531
2526
|
) }),
|
|
2532
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2527
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.FormMessage, {})
|
|
2533
2528
|
] })
|
|
2534
2529
|
}
|
|
2535
2530
|
),
|
|
2536
2531
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3 pt-4", children: [
|
|
2537
2532
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2538
|
-
|
|
2533
|
+
uiCore.Button,
|
|
2539
2534
|
{
|
|
2540
2535
|
type: "button",
|
|
2541
2536
|
variant: "outline",
|
|
@@ -2544,7 +2539,7 @@ var CreateTicketDialog = () => {
|
|
|
2544
2539
|
children: "Cancel"
|
|
2545
2540
|
}
|
|
2546
2541
|
),
|
|
2547
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2542
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2548
2543
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2549
2544
|
"Creating..."
|
|
2550
2545
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2570,7 +2565,7 @@ var SupportLayoutContent = () => {
|
|
|
2570
2565
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b bg-background flex-shrink-0", children: [
|
|
2571
2566
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2572
2567
|
selectedTicket ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2573
|
-
|
|
2568
|
+
uiCore.Button,
|
|
2574
2569
|
{
|
|
2575
2570
|
variant: "ghost",
|
|
2576
2571
|
size: "sm",
|
|
@@ -2582,7 +2577,7 @@ var SupportLayoutContent = () => {
|
|
|
2582
2577
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: selectedTicket ? selectedTicket.subject : "Support" }),
|
|
2583
2578
|
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 })
|
|
2584
2579
|
] }),
|
|
2585
|
-
!selectedTicket && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2580
|
+
!selectedTicket && /* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: openCreateDialog, size: "sm", children: [
|
|
2586
2581
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2587
2582
|
"New Ticket"
|
|
2588
2583
|
] })
|
|
@@ -2610,15 +2605,15 @@ var SupportLayoutContent = () => {
|
|
|
2610
2605
|
] }),
|
|
2611
2606
|
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 })
|
|
2612
2607
|
] }),
|
|
2613
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2608
|
+
/* @__PURE__ */ jsxRuntime.jsxs(uiCore.Button, { onClick: openCreateDialog, children: [
|
|
2614
2609
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 mr-2" }),
|
|
2615
2610
|
"New Ticket"
|
|
2616
2611
|
] })
|
|
2617
2612
|
] }),
|
|
2618
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2619
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2620
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2621
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2613
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(uiCore.ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [
|
|
2614
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizablePanel, { defaultSize: 35, minSize: 25, maxSize: 50, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full border-r overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(TicketList, {}) }) }),
|
|
2615
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizableHandle, { withHandle: true, className: "hover:bg-accent transition-colors" }),
|
|
2616
|
+
/* @__PURE__ */ jsxRuntime.jsx(uiCore.ResizablePanel, { defaultSize: 65, minSize: 50, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [
|
|
2622
2617
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(MessageList, {}) }),
|
|
2623
2618
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(MessageInput, {}) })
|
|
2624
2619
|
] }) })
|
|
@@ -2633,7 +2628,7 @@ var SupportLayout = () => {
|
|
|
2633
2628
|
// package.json
|
|
2634
2629
|
var package_default = {
|
|
2635
2630
|
name: "@djangocfg/ext-support",
|
|
2636
|
-
version: "1.0.
|
|
2631
|
+
version: "1.0.9",
|
|
2637
2632
|
description: "Support ticket system extension for DjangoCFG",
|
|
2638
2633
|
keywords: [
|
|
2639
2634
|
"django",
|
|
@@ -2694,7 +2689,7 @@ var package_default = {
|
|
|
2694
2689
|
peerDependencies: {
|
|
2695
2690
|
"@djangocfg/api": "workspace:*",
|
|
2696
2691
|
"@djangocfg/ext-base": "workspace:*",
|
|
2697
|
-
"@djangocfg/ui-
|
|
2692
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2698
2693
|
consola: "^3.4.2",
|
|
2699
2694
|
"lucide-react": "^0.545.0",
|
|
2700
2695
|
moment: "^2.30.1",
|
|
@@ -2708,6 +2703,7 @@ var package_default = {
|
|
|
2708
2703
|
devDependencies: {
|
|
2709
2704
|
"@djangocfg/api": "workspace:*",
|
|
2710
2705
|
"@djangocfg/ext-base": "workspace:*",
|
|
2706
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2711
2707
|
"@djangocfg/typescript-config": "workspace:*",
|
|
2712
2708
|
"@types/node": "^24.7.2",
|
|
2713
2709
|
"@types/react": "^19.0.0",
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,14 @@ import { z } from 'zod';
|
|
|
4
4
|
import { createExtensionAPI } from '@djangocfg/ext-base/api';
|
|
5
5
|
import { ArrowLeft, LifeBuoy, Plus, MessageSquare, Loader2, Send, Headphones, User, Clock } from 'lucide-react';
|
|
6
6
|
import React7, { createContext, useState, useCallback, useEffect, useContext, useRef } from 'react';
|
|
7
|
-
import { Button, ResizablePanelGroup, ResizablePanel, ResizableHandle, Skeleton, ScrollArea,
|
|
7
|
+
import { Button, ResizablePanelGroup, ResizablePanel, ResizableHandle, Skeleton, ScrollArea, Textarea, useToast as useToast$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Avatar, AvatarImage, AvatarFallback, Card, CardContent, Badge } from '@djangocfg/ui-core';
|
|
8
8
|
import useSWR, { useSWRConfig } from 'swr';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import moment2 from 'moment';
|
|
11
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
11
12
|
import { useAuth } from '@djangocfg/api/auth';
|
|
12
13
|
import useSWRInfinite from 'swr/infinite';
|
|
14
|
+
import { useToast } from '@djangocfg/ui-core/hooks';
|
|
13
15
|
import { useForm } from 'react-hook-form';
|
|
14
16
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
15
17
|
import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
@@ -2392,17 +2394,10 @@ var MessageInput = () => {
|
|
|
2392
2394
|
try {
|
|
2393
2395
|
await sendMessage(message.trim());
|
|
2394
2396
|
setMessage("");
|
|
2395
|
-
toast(
|
|
2396
|
-
title: "Success",
|
|
2397
|
-
description: "Message sent successfully"
|
|
2398
|
-
});
|
|
2397
|
+
toast.success("Message sent successfully");
|
|
2399
2398
|
} catch (error) {
|
|
2400
2399
|
supportLogger.error("Failed to send message:", error);
|
|
2401
|
-
toast(
|
|
2402
|
-
title: "Error",
|
|
2403
|
-
description: "Failed to send message",
|
|
2404
|
-
variant: "destructive"
|
|
2405
|
-
});
|
|
2400
|
+
toast.error("Failed to send message");
|
|
2406
2401
|
} finally {
|
|
2407
2402
|
setIsSending(false);
|
|
2408
2403
|
}
|
|
@@ -2450,7 +2445,7 @@ var createTicketSchema = z.object({
|
|
|
2450
2445
|
});
|
|
2451
2446
|
var CreateTicketDialog = () => {
|
|
2452
2447
|
const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
|
|
2453
|
-
const { toast } = useToast();
|
|
2448
|
+
const { toast } = useToast$1();
|
|
2454
2449
|
const [isSubmitting, setIsSubmitting] = React7.useState(false);
|
|
2455
2450
|
const form = useForm({
|
|
2456
2451
|
resolver: zodResolver(createTicketSchema),
|
|
@@ -2623,7 +2618,7 @@ var SupportLayout = () => {
|
|
|
2623
2618
|
// package.json
|
|
2624
2619
|
var package_default = {
|
|
2625
2620
|
name: "@djangocfg/ext-support",
|
|
2626
|
-
version: "1.0.
|
|
2621
|
+
version: "1.0.9",
|
|
2627
2622
|
description: "Support ticket system extension for DjangoCFG",
|
|
2628
2623
|
keywords: [
|
|
2629
2624
|
"django",
|
|
@@ -2684,7 +2679,7 @@ var package_default = {
|
|
|
2684
2679
|
peerDependencies: {
|
|
2685
2680
|
"@djangocfg/api": "workspace:*",
|
|
2686
2681
|
"@djangocfg/ext-base": "workspace:*",
|
|
2687
|
-
"@djangocfg/ui-
|
|
2682
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2688
2683
|
consola: "^3.4.2",
|
|
2689
2684
|
"lucide-react": "^0.545.0",
|
|
2690
2685
|
moment: "^2.30.1",
|
|
@@ -2698,6 +2693,7 @@ var package_default = {
|
|
|
2698
2693
|
devDependencies: {
|
|
2699
2694
|
"@djangocfg/api": "workspace:*",
|
|
2700
2695
|
"@djangocfg/ext-base": "workspace:*",
|
|
2696
|
+
"@djangocfg/ui-core": "workspace:*",
|
|
2701
2697
|
"@djangocfg/typescript-config": "workspace:*",
|
|
2702
2698
|
"@types/node": "^24.7.2",
|
|
2703
2699
|
"@types/react": "^19.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ext-support",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Support ticket system extension for DjangoCFG",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"django",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"check": "tsc --noEmit"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@djangocfg/api": "^2.1.
|
|
63
|
-
"@djangocfg/ext-base": "^1.0.
|
|
64
|
-
"@djangocfg/ui-
|
|
62
|
+
"@djangocfg/api": "^2.1.104",
|
|
63
|
+
"@djangocfg/ext-base": "^1.0.8",
|
|
64
|
+
"@djangocfg/ui-core": "^2.1.104",
|
|
65
65
|
"consola": "^3.4.2",
|
|
66
66
|
"lucide-react": "^0.545.0",
|
|
67
67
|
"moment": "^2.30.1",
|
|
@@ -73,9 +73,10 @@
|
|
|
73
73
|
"zod": "^4.1.13"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@djangocfg/api": "^2.1.
|
|
77
|
-
"@djangocfg/ext-base": "^1.0.
|
|
78
|
-
"@djangocfg/
|
|
76
|
+
"@djangocfg/api": "^2.1.104",
|
|
77
|
+
"@djangocfg/ext-base": "^1.0.8",
|
|
78
|
+
"@djangocfg/ui-core": "^2.1.104",
|
|
79
|
+
"@djangocfg/typescript-config": "^2.1.104",
|
|
79
80
|
"@types/node": "^24.7.2",
|
|
80
81
|
"@types/react": "^19.0.0",
|
|
81
82
|
"consola": "^3.4.2",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { ArrowLeft, LifeBuoy, Plus } from 'lucide-react';
|
|
10
10
|
import React from 'react';
|
|
11
11
|
|
|
12
|
-
import { Button, ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@djangocfg/ui-
|
|
12
|
+
import { Button, ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@djangocfg/ui-core';
|
|
13
13
|
|
|
14
14
|
import { SupportProvider } from '../../contexts/SupportContext';
|
|
15
15
|
import { CreateTicketDialog, MessageInput, MessageList, TicketList } from './components';
|
|
@@ -14,7 +14,7 @@ import { z } from 'zod';
|
|
|
14
14
|
import {
|
|
15
15
|
Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Form, FormControl,
|
|
16
16
|
FormField, FormItem, FormLabel, FormMessage, Input, Textarea, useToast
|
|
17
|
-
} from '@djangocfg/ui-
|
|
17
|
+
} from '@djangocfg/ui-core';
|
|
18
18
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
19
19
|
|
|
20
20
|
import { supportLogger } from '../../../utils/logger';
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
import { Send } from 'lucide-react';
|
|
9
9
|
import React, { useState } from 'react';
|
|
10
10
|
|
|
11
|
-
import { Button, Textarea
|
|
11
|
+
import { Button, Textarea } from '@djangocfg/ui-core';
|
|
12
|
+
import { useToast } from '@djangocfg/ui-core/hooks';
|
|
12
13
|
|
|
13
14
|
import { supportLogger } from '../../../utils/logger';
|
|
14
15
|
import { useSupportLayoutContext } from '../context';
|
|
@@ -28,17 +29,10 @@ export const MessageInput: React.FC = () => {
|
|
|
28
29
|
try {
|
|
29
30
|
await sendMessage(message.trim());
|
|
30
31
|
setMessage('');
|
|
31
|
-
toast(
|
|
32
|
-
title: 'Success',
|
|
33
|
-
description: 'Message sent successfully',
|
|
34
|
-
});
|
|
32
|
+
toast.success('Message sent successfully');
|
|
35
33
|
} catch (error) {
|
|
36
34
|
supportLogger.error('Failed to send message:', error);
|
|
37
|
-
toast(
|
|
38
|
-
title: 'Error',
|
|
39
|
-
description: 'Failed to send message',
|
|
40
|
-
variant: 'destructive',
|
|
41
|
-
});
|
|
35
|
+
toast.error('Failed to send message');
|
|
42
36
|
} finally {
|
|
43
37
|
setIsSending(false);
|
|
44
38
|
}
|
|
@@ -12,7 +12,7 @@ import React, { useCallback, useEffect, useRef } from 'react';
|
|
|
12
12
|
import { useAuth } from '@djangocfg/api/auth';
|
|
13
13
|
import {
|
|
14
14
|
Avatar, AvatarFallback, AvatarImage, Button, Card, CardContent, ScrollArea, Skeleton
|
|
15
|
-
} from '@djangocfg/ui-
|
|
15
|
+
} from '@djangocfg/ui-core';
|
|
16
16
|
|
|
17
17
|
import { useSupportLayoutContext } from '../context';
|
|
18
18
|
import { useInfiniteMessages } from '../hooks';
|
|
@@ -9,7 +9,8 @@ import { Clock, MessageSquare } from 'lucide-react';
|
|
|
9
9
|
import moment from 'moment';
|
|
10
10
|
import React from 'react';
|
|
11
11
|
|
|
12
|
-
import { Badge, Card, CardContent
|
|
12
|
+
import { Badge, Card, CardContent } from '@djangocfg/ui-core';
|
|
13
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
13
14
|
|
|
14
15
|
import type { Ticket } from '../../../api/generated/ext_support/_utils/schemas';
|
|
15
16
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { Loader2, MessageSquare } from 'lucide-react';
|
|
9
9
|
import React, { useEffect, useRef } from 'react';
|
|
10
10
|
|
|
11
|
-
import { Button, ScrollArea, Skeleton } from '@djangocfg/ui-
|
|
11
|
+
import { Button, ScrollArea, Skeleton } from '@djangocfg/ui-core';
|
|
12
12
|
|
|
13
13
|
import { useSupportLayoutContext } from '../context';
|
|
14
14
|
import { SUPPORT_LAYOUT_EVENTS } from '../events';
|