@djangocfg/ext-support 1.0.24 → 1.0.26
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 +1 -1
- package/dist/config.js +1 -1
- package/dist/hooks.cjs +398 -334
- package/dist/hooks.d.cts +6 -2
- package/dist/hooks.d.ts +6 -2
- package/dist/hooks.js +356 -291
- package/dist/i18n.cjs +72 -72
- package/dist/i18n.js +73 -73
- package/dist/index-D-xo66K9.d.cts +862 -0
- package/dist/index-D-xo66K9.d.ts +863 -0
- package/dist/index-Dov7pn8Z.d.ts +2 -1
- package/dist/index-rR_XqXq1.d.cts +838 -0
- package/dist/index-rR_XqXq1.d.ts +838 -0
- package/dist/index.cjs +398 -334
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +356 -291
- package/package.json +8 -8
- package/src/adapters/api.ts +4 -5
- package/src/adapters/demo.ts +2 -1
- package/src/api/generated/ext_support/_utils/fetchers/ext_support__support.ts +4 -4
- package/src/api/generated/ext_support/_utils/hooks/ext_support__support.ts +2 -2
- package/src/api/generated/ext_support/_utils/schemas/Ticket.schema.ts +1 -1
- package/src/api/generated/ext_support/_utils/schemas/TicketRequest.schema.ts +1 -1
- package/src/api/generated/ext_support/enums.ts +0 -30
- package/src/api/generated/ext_support/ext_support__support/client.ts +6 -6
- package/src/api/generated/ext_support/ext_support__support/models.ts +2 -2
- package/src/api/generated/ext_support/schema.json +36 -0
- package/src/components/CreateTicketSheet.tsx +7 -12
- package/src/components/SupportHero.tsx +35 -47
- package/src/components/TicketItem.tsx +28 -74
- package/src/components/TicketList.tsx +30 -23
- package/src/components/TicketSheet.tsx +246 -162
- package/src/contexts/SupportExtensionProvider.tsx +4 -4
- package/src/contexts/types.ts +2 -2
- package/src/i18n/useSupportT.ts +3 -3
- package/src/utils/status.ts +44 -0
- package/src/utils/time.ts +88 -0
package/dist/index.js
CHANGED
|
@@ -2,16 +2,16 @@ import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/
|
|
|
2
2
|
import { createConsola, consola } from 'consola';
|
|
3
3
|
import pRetry, { AbortError } from 'p-retry';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import
|
|
5
|
+
import { createContext, useMemo, useCallback, useRef, useEffect, useState, useContext } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import useSWRInfinite from 'swr/infinite';
|
|
8
8
|
import { useAuth } from '@djangocfg/api/auth';
|
|
9
9
|
import { useSWRConfig } from 'swr';
|
|
10
|
-
import {
|
|
10
|
+
import { RefreshCw, MessageSquare, Loader2, ArrowUp, Headphones, User } from 'lucide-react';
|
|
11
11
|
import { useLocale } from 'next-intl';
|
|
12
|
-
import { Skeleton, Button,
|
|
12
|
+
import { Skeleton, Button, Empty, EmptyMedia, EmptyTitle, EmptyDescription, useToast, ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, ResponsiveSheetTitle, ScrollArea, ResponsiveSheetDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Textarea, Avatar, AvatarImage, AvatarFallback } from '@djangocfg/ui-core';
|
|
13
13
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
14
|
-
import
|
|
14
|
+
import moment from 'moment';
|
|
15
15
|
import { useForm } from 'react-hook-form';
|
|
16
16
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
17
17
|
import { createExtensionConfig } from '@djangocfg/ext-base';
|
|
@@ -33,7 +33,7 @@ var ExtSupportSupport = class {
|
|
|
33
33
|
if (isParamsObject) {
|
|
34
34
|
params = args[0];
|
|
35
35
|
} else {
|
|
36
|
-
params = {
|
|
36
|
+
params = { ordering: args[0], page: args[1], page_size: args[2], search: args[3] };
|
|
37
37
|
}
|
|
38
38
|
const response = await this.client.request("GET", "/cfg/support/tickets/", { params });
|
|
39
39
|
return response;
|
|
@@ -58,7 +58,7 @@ var ExtSupportSupport = class {
|
|
|
58
58
|
if (isParamsObject) {
|
|
59
59
|
params = args[1];
|
|
60
60
|
} else {
|
|
61
|
-
params = {
|
|
61
|
+
params = { ordering: args[1], page: args[2], page_size: args[3], search: args[4] };
|
|
62
62
|
}
|
|
63
63
|
const response = await this.client.request("GET", `/cfg/support/tickets/${ticket_uuid}/messages/`, { params });
|
|
64
64
|
return response;
|
|
@@ -749,22 +749,6 @@ var PatchedTicketRequestStatus = /* @__PURE__ */ ((PatchedTicketRequestStatus2)
|
|
|
749
749
|
PatchedTicketRequestStatus2["CLOSED"] = "closed";
|
|
750
750
|
return PatchedTicketRequestStatus2;
|
|
751
751
|
})(PatchedTicketRequestStatus || {});
|
|
752
|
-
var TicketStatus = /* @__PURE__ */ ((TicketStatus2) => {
|
|
753
|
-
TicketStatus2["OPEN"] = "open";
|
|
754
|
-
TicketStatus2["WAITING_FOR_USER"] = "waiting_for_user";
|
|
755
|
-
TicketStatus2["WAITING_FOR_ADMIN"] = "waiting_for_admin";
|
|
756
|
-
TicketStatus2["RESOLVED"] = "resolved";
|
|
757
|
-
TicketStatus2["CLOSED"] = "closed";
|
|
758
|
-
return TicketStatus2;
|
|
759
|
-
})(TicketStatus || {});
|
|
760
|
-
var TicketRequestStatus = /* @__PURE__ */ ((TicketRequestStatus2) => {
|
|
761
|
-
TicketRequestStatus2["OPEN"] = "open";
|
|
762
|
-
TicketRequestStatus2["WAITING_FOR_USER"] = "waiting_for_user";
|
|
763
|
-
TicketRequestStatus2["WAITING_FOR_ADMIN"] = "waiting_for_admin";
|
|
764
|
-
TicketRequestStatus2["RESOLVED"] = "resolved";
|
|
765
|
-
TicketRequestStatus2["CLOSED"] = "closed";
|
|
766
|
-
return TicketRequestStatus2;
|
|
767
|
-
})(TicketRequestStatus || {});
|
|
768
752
|
var SenderSchema = z.object({
|
|
769
753
|
id: z.int(),
|
|
770
754
|
display_username: z.string(),
|
|
@@ -808,7 +792,7 @@ var TicketSchema = z.object({
|
|
|
808
792
|
uuid: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i),
|
|
809
793
|
user: z.int(),
|
|
810
794
|
subject: z.string().max(255),
|
|
811
|
-
status: z.nativeEnum(
|
|
795
|
+
status: z.nativeEnum(PatchedTicketRequestStatus).optional(),
|
|
812
796
|
created_at: z.string().datetime({ offset: true }),
|
|
813
797
|
unanswered_messages_count: z.int()
|
|
814
798
|
});
|
|
@@ -836,7 +820,7 @@ z.object({
|
|
|
836
820
|
z.object({
|
|
837
821
|
user: z.int(),
|
|
838
822
|
subject: z.string().min(1).max(255),
|
|
839
|
-
status: z.nativeEnum(
|
|
823
|
+
status: z.nativeEnum(PatchedTicketRequestStatus).optional()
|
|
840
824
|
});
|
|
841
825
|
|
|
842
826
|
// src/api/generated/ext_support/api-instance.ts
|
|
@@ -872,7 +856,7 @@ function configureAPI(config) {
|
|
|
872
856
|
// src/api/generated/ext_support/_utils/fetchers/ext_support__support.ts
|
|
873
857
|
async function getSupportTicketsList(params, client) {
|
|
874
858
|
const api = getAPIInstance();
|
|
875
|
-
const response = await api.ext_support_support.ticketsList(params?.page, params?.page_size);
|
|
859
|
+
const response = await api.ext_support_support.ticketsList(params?.ordering, params?.page, params?.page_size, params?.search);
|
|
876
860
|
try {
|
|
877
861
|
return PaginatedTicketListSchema.parse(response);
|
|
878
862
|
} catch (error) {
|
|
@@ -956,7 +940,7 @@ Method: POST`);
|
|
|
956
940
|
}
|
|
957
941
|
async function getSupportTicketsMessagesList(ticket_uuid, params, client) {
|
|
958
942
|
const api = getAPIInstance();
|
|
959
|
-
const response = await api.ext_support_support.ticketsMessagesList(ticket_uuid, params?.page, params?.page_size);
|
|
943
|
+
const response = await api.ext_support_support.ticketsMessagesList(ticket_uuid, params?.ordering, params?.page, params?.page_size, params?.search);
|
|
960
944
|
try {
|
|
961
945
|
return PaginatedMessageListSchema.parse(response);
|
|
962
946
|
} catch (error) {
|
|
@@ -1711,78 +1695,6 @@ var en = {
|
|
|
1711
1695
|
}
|
|
1712
1696
|
};
|
|
1713
1697
|
|
|
1714
|
-
// src/i18n/locales/ru.ts
|
|
1715
|
-
var ru = {
|
|
1716
|
-
layout: {
|
|
1717
|
-
title: "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1718
|
-
titleShort: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430",
|
|
1719
|
-
subtitle: "\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u0435 \u043F\u043E\u043C\u043E\u0449\u044C \u043E\u0442 \u043D\u0430\u0448\u0435\u0439 \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1720
|
-
newTicket: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
1721
|
-
},
|
|
1722
|
-
hero: {
|
|
1723
|
-
openTickets: "\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
1724
|
-
unreadMessages: "\u041D\u0435\u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445"
|
|
1725
|
-
},
|
|
1726
|
-
status: {
|
|
1727
|
-
open: "\u041E\u0442\u043A\u0440\u044B\u0442",
|
|
1728
|
-
waitingForUser: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0430\u0441",
|
|
1729
|
-
waitingForAdmin: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0443",
|
|
1730
|
-
resolved: "\u0420\u0435\u0448\u0451\u043D",
|
|
1731
|
-
closed: "\u0417\u0430\u043A\u0440\u044B\u0442"
|
|
1732
|
-
},
|
|
1733
|
-
ticketList: {
|
|
1734
|
-
noTickets: "\u041D\u0435\u0442 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
1735
|
-
noTicketsDescription: "\u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043F\u0435\u0440\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043F\u043E\u043C\u043E\u0449\u044C",
|
|
1736
|
-
loadingMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430...",
|
|
1737
|
-
loadMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0451",
|
|
1738
|
-
allLoaded: "\u0412\u0441\u0435 {count} \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E"
|
|
1739
|
-
},
|
|
1740
|
-
createTicket: {
|
|
1741
|
-
title: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
1742
|
-
description: "\u041E\u043F\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443, \u0438 \u043C\u044B \u043F\u043E\u043C\u043E\u0436\u0435\u043C \u0432\u0430\u043C",
|
|
1743
|
-
subjectLabel: "\u0422\u0435\u043C\u0430",
|
|
1744
|
-
subjectPlaceholder: "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B",
|
|
1745
|
-
messageLabel: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
1746
|
-
messagePlaceholder: "\u041E\u043F\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443 \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u043E...",
|
|
1747
|
-
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
1748
|
-
creating: "\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435...",
|
|
1749
|
-
create: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
1750
|
-
},
|
|
1751
|
-
validation: {
|
|
1752
|
-
subjectRequired: "\u0422\u0435\u043C\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u0430",
|
|
1753
|
-
subjectTooLong: "\u0422\u0435\u043C\u0430 \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u0430\u044F (\u043C\u0430\u043A\u0441. 200 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432)",
|
|
1754
|
-
messageRequired: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E",
|
|
1755
|
-
messageTooLong: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u043E\u0435 (\u043C\u0430\u043A\u0441. 5000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432)"
|
|
1756
|
-
},
|
|
1757
|
-
messages: {
|
|
1758
|
-
ticketCreated: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u043E",
|
|
1759
|
-
ticketCreateFailed: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
1760
|
-
messageSent: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
1761
|
-
messageSendFailed: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435"
|
|
1762
|
-
},
|
|
1763
|
-
messageInput: {
|
|
1764
|
-
placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435...",
|
|
1765
|
-
ticketClosed: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E",
|
|
1766
|
-
ticketClosedDescription: "\u042D\u0442\u043E \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E. \u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043D\u043E\u0432\u043E\u0435, \u0435\u0441\u043B\u0438 \u0432\u0430\u043C \u043D\u0443\u0436\u043D\u0430 \u043F\u043E\u043C\u043E\u0449\u044C."
|
|
1767
|
-
},
|
|
1768
|
-
messageList: {
|
|
1769
|
-
noTicketSelected: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E",
|
|
1770
|
-
noTicketSelectedDescription: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430 \u0434\u043B\u044F \u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
1771
|
-
noMessages: "\u041D\u0435\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
1772
|
-
noMessagesDescription: "\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u0434\u0438\u0430\u043B\u043E\u0433, \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0432 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
1773
|
-
loadingOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u0442\u0430\u0440\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439...",
|
|
1774
|
-
loadOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u0442\u0430\u0440\u044B\u0435",
|
|
1775
|
-
supportTeam: "\u0421\u043B\u0443\u0436\u0431\u0430 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1776
|
-
staff: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A"
|
|
1777
|
-
},
|
|
1778
|
-
time: {
|
|
1779
|
-
justNow: "\u0422\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E",
|
|
1780
|
-
minutesAgo: "{count} \u043C\u0438\u043D \u043D\u0430\u0437\u0430\u0434",
|
|
1781
|
-
hoursAgo: "{count}\u0447 \u043D\u0430\u0437\u0430\u0434",
|
|
1782
|
-
daysAgo: "{count}\u0434 \u043D\u0430\u0437\u0430\u0434"
|
|
1783
|
-
}
|
|
1784
|
-
};
|
|
1785
|
-
|
|
1786
1698
|
// src/i18n/locales/ko.ts
|
|
1787
1699
|
var ko = {
|
|
1788
1700
|
layout: {
|
|
@@ -1855,6 +1767,78 @@ var ko = {
|
|
|
1855
1767
|
}
|
|
1856
1768
|
};
|
|
1857
1769
|
|
|
1770
|
+
// src/i18n/locales/ru.ts
|
|
1771
|
+
var ru = {
|
|
1772
|
+
layout: {
|
|
1773
|
+
title: "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1774
|
+
titleShort: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430",
|
|
1775
|
+
subtitle: "\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u0435 \u043F\u043E\u043C\u043E\u0449\u044C \u043E\u0442 \u043D\u0430\u0448\u0435\u0439 \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1776
|
+
newTicket: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
1777
|
+
},
|
|
1778
|
+
hero: {
|
|
1779
|
+
openTickets: "\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
1780
|
+
unreadMessages: "\u041D\u0435\u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445"
|
|
1781
|
+
},
|
|
1782
|
+
status: {
|
|
1783
|
+
open: "\u041E\u0442\u043A\u0440\u044B\u0442",
|
|
1784
|
+
waitingForUser: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0430\u0441",
|
|
1785
|
+
waitingForAdmin: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0443",
|
|
1786
|
+
resolved: "\u0420\u0435\u0448\u0451\u043D",
|
|
1787
|
+
closed: "\u0417\u0430\u043A\u0440\u044B\u0442"
|
|
1788
|
+
},
|
|
1789
|
+
ticketList: {
|
|
1790
|
+
noTickets: "\u041D\u0435\u0442 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
1791
|
+
noTicketsDescription: "\u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043F\u0435\u0440\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043F\u043E\u043C\u043E\u0449\u044C",
|
|
1792
|
+
loadingMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430...",
|
|
1793
|
+
loadMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0451",
|
|
1794
|
+
allLoaded: "\u0412\u0441\u0435 {count} \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E"
|
|
1795
|
+
},
|
|
1796
|
+
createTicket: {
|
|
1797
|
+
title: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
1798
|
+
description: "\u041E\u043F\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443, \u0438 \u043C\u044B \u043F\u043E\u043C\u043E\u0436\u0435\u043C \u0432\u0430\u043C",
|
|
1799
|
+
subjectLabel: "\u0422\u0435\u043C\u0430",
|
|
1800
|
+
subjectPlaceholder: "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B",
|
|
1801
|
+
messageLabel: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
1802
|
+
messagePlaceholder: "\u041E\u043F\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443 \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u043E...",
|
|
1803
|
+
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
1804
|
+
creating: "\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435...",
|
|
1805
|
+
create: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
1806
|
+
},
|
|
1807
|
+
validation: {
|
|
1808
|
+
subjectRequired: "\u0422\u0435\u043C\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u0430",
|
|
1809
|
+
subjectTooLong: "\u0422\u0435\u043C\u0430 \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u0430\u044F (\u043C\u0430\u043A\u0441. 200 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432)",
|
|
1810
|
+
messageRequired: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E",
|
|
1811
|
+
messageTooLong: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u043E\u0435 (\u043C\u0430\u043A\u0441. 5000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432)"
|
|
1812
|
+
},
|
|
1813
|
+
messages: {
|
|
1814
|
+
ticketCreated: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u043E",
|
|
1815
|
+
ticketCreateFailed: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
1816
|
+
messageSent: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
1817
|
+
messageSendFailed: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435"
|
|
1818
|
+
},
|
|
1819
|
+
messageInput: {
|
|
1820
|
+
placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435...",
|
|
1821
|
+
ticketClosed: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E",
|
|
1822
|
+
ticketClosedDescription: "\u042D\u0442\u043E \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E. \u0421\u043E\u0437\u0434\u0430\u0439\u0442\u0435 \u043D\u043E\u0432\u043E\u0435, \u0435\u0441\u043B\u0438 \u0432\u0430\u043C \u043D\u0443\u0436\u043D\u0430 \u043F\u043E\u043C\u043E\u0449\u044C."
|
|
1823
|
+
},
|
|
1824
|
+
messageList: {
|
|
1825
|
+
noTicketSelected: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E",
|
|
1826
|
+
noTicketSelectedDescription: "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430 \u0434\u043B\u044F \u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
1827
|
+
noMessages: "\u041D\u0435\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
1828
|
+
noMessagesDescription: "\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u0434\u0438\u0430\u043B\u043E\u0433, \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0432 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
1829
|
+
loadingOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u0442\u0430\u0440\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439...",
|
|
1830
|
+
loadOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u0442\u0430\u0440\u044B\u0435",
|
|
1831
|
+
supportTeam: "\u0421\u043B\u0443\u0436\u0431\u0430 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
1832
|
+
staff: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A"
|
|
1833
|
+
},
|
|
1834
|
+
time: {
|
|
1835
|
+
justNow: "\u0422\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E",
|
|
1836
|
+
minutesAgo: "{count} \u043C\u0438\u043D \u043D\u0430\u0437\u0430\u0434",
|
|
1837
|
+
hoursAgo: "{count}\u0447 \u043D\u0430\u0437\u0430\u0434",
|
|
1838
|
+
daysAgo: "{count}\u0434 \u043D\u0430\u0437\u0430\u0434"
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1858
1842
|
// src/i18n/useSupportT.ts
|
|
1859
1843
|
var translations = { en, ru, ko };
|
|
1860
1844
|
function getNestedValue(obj, path) {
|
|
@@ -1888,27 +1872,22 @@ function SupportHero({ onCreateTicket, className }) {
|
|
|
1888
1872
|
unreadMessages: st("hero.unreadMessages")
|
|
1889
1873
|
}), [st]);
|
|
1890
1874
|
const openTicketsCount = tickets.filter((t) => t.status !== "closed" && t.status !== "resolved").length;
|
|
1891
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center py-
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-
|
|
1894
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
/* @__PURE__ */ jsx("
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1902
|
-
/* @__PURE__ */ jsxs(
|
|
1875
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center py-12 px-4", className), children: [
|
|
1876
|
+
isLoadingTickets ? /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-48 mx-auto mb-2" }),
|
|
1878
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-64 mx-auto" })
|
|
1879
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1880
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight", children: labels.title }),
|
|
1881
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground mt-2", children: labels.subtitle })
|
|
1882
|
+
] }),
|
|
1883
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mt-6", children: [
|
|
1884
|
+
/* @__PURE__ */ jsx(
|
|
1903
1885
|
Button,
|
|
1904
1886
|
{
|
|
1905
1887
|
size: "lg",
|
|
1906
1888
|
onClick: onCreateTicket,
|
|
1907
|
-
className: "rounded-full px-
|
|
1908
|
-
children:
|
|
1909
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-5 w-5 mr-2" }),
|
|
1910
|
-
labels.newTicket
|
|
1911
|
-
]
|
|
1889
|
+
className: "rounded-full px-8 h-12 text-base",
|
|
1890
|
+
children: labels.newTicket
|
|
1912
1891
|
}
|
|
1913
1892
|
),
|
|
1914
1893
|
/* @__PURE__ */ jsx(
|
|
@@ -1917,43 +1896,100 @@ function SupportHero({ onCreateTicket, className }) {
|
|
|
1917
1896
|
size: "icon",
|
|
1918
1897
|
variant: "ghost",
|
|
1919
1898
|
onClick: () => refreshTickets(),
|
|
1920
|
-
className: "rounded-full",
|
|
1899
|
+
className: "rounded-full h-10 w-10",
|
|
1921
1900
|
children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" })
|
|
1922
1901
|
}
|
|
1923
1902
|
)
|
|
1924
1903
|
] }),
|
|
1925
|
-
!isLoadingTickets && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
1926
|
-
/* @__PURE__ */ jsxs("
|
|
1927
|
-
|
|
1928
|
-
|
|
1904
|
+
!isLoadingTickets && (openTicketsCount > 0 || unreadCount > 0) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-4", children: [
|
|
1905
|
+
openTicketsCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground bg-muted px-3 py-1 rounded-full", children: [
|
|
1906
|
+
openTicketsCount,
|
|
1907
|
+
" ",
|
|
1908
|
+
labels.openTickets.toLowerCase()
|
|
1929
1909
|
] }),
|
|
1930
|
-
/* @__PURE__ */
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
unreadCount > 0 ? "text-destructive" : "text-foreground"
|
|
1935
|
-
), children: unreadCount }),
|
|
1936
|
-
/* @__PURE__ */ jsx("span", { children: labels.unreadMessages })
|
|
1910
|
+
unreadCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-destructive bg-destructive/10 px-3 py-1 rounded-full", children: [
|
|
1911
|
+
unreadCount,
|
|
1912
|
+
" ",
|
|
1913
|
+
labels.unreadMessages.toLowerCase()
|
|
1937
1914
|
] })
|
|
1938
1915
|
] })
|
|
1939
1916
|
] });
|
|
1940
1917
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1918
|
+
|
|
1919
|
+
// src/utils/status.ts
|
|
1920
|
+
var ticketStatusConfig = {
|
|
1921
|
+
open: {
|
|
1922
|
+
color: "text-blue-600 dark:text-blue-400",
|
|
1923
|
+
bg: "bg-blue-500/10"
|
|
1924
|
+
},
|
|
1925
|
+
waiting_for_user: {
|
|
1926
|
+
color: "text-orange-600 dark:text-orange-400",
|
|
1927
|
+
bg: "bg-orange-500/10"
|
|
1928
|
+
},
|
|
1929
|
+
waiting_for_admin: {
|
|
1930
|
+
color: "text-muted-foreground",
|
|
1931
|
+
bg: "bg-muted"
|
|
1932
|
+
},
|
|
1933
|
+
resolved: {
|
|
1934
|
+
color: "text-green-600 dark:text-green-400",
|
|
1935
|
+
bg: "bg-green-500/10"
|
|
1936
|
+
},
|
|
1937
|
+
closed: {
|
|
1938
|
+
color: "text-muted-foreground",
|
|
1939
|
+
bg: "bg-muted"
|
|
1955
1940
|
}
|
|
1956
1941
|
};
|
|
1942
|
+
function getStatusConfig(status) {
|
|
1943
|
+
return ticketStatusConfig[status] || ticketStatusConfig.open;
|
|
1944
|
+
}
|
|
1945
|
+
function formatMessageTime(date) {
|
|
1946
|
+
if (!date) return "";
|
|
1947
|
+
return moment.utc(date).local().format("h:mm A");
|
|
1948
|
+
}
|
|
1949
|
+
function formatDateSeparator(date) {
|
|
1950
|
+
if (!date) return "";
|
|
1951
|
+
const m = moment.utc(date).local();
|
|
1952
|
+
const now = moment();
|
|
1953
|
+
const today = now.clone().startOf("day");
|
|
1954
|
+
const yesterday = now.clone().subtract(1, "day").startOf("day");
|
|
1955
|
+
if (m.isSame(today, "day")) {
|
|
1956
|
+
return "Today";
|
|
1957
|
+
}
|
|
1958
|
+
if (m.isSame(yesterday, "day")) {
|
|
1959
|
+
return "Yesterday";
|
|
1960
|
+
}
|
|
1961
|
+
if (m.isSame(now, "year")) {
|
|
1962
|
+
return m.format("MMM D");
|
|
1963
|
+
}
|
|
1964
|
+
return m.format("MMM D, YYYY");
|
|
1965
|
+
}
|
|
1966
|
+
function formatRelativeTime(date, labels) {
|
|
1967
|
+
if (!date) return "N/A";
|
|
1968
|
+
const m = moment.utc(date).local();
|
|
1969
|
+
const now = moment();
|
|
1970
|
+
const diffInSeconds = now.diff(m, "seconds");
|
|
1971
|
+
if (diffInSeconds < 60) {
|
|
1972
|
+
return labels.justNow;
|
|
1973
|
+
}
|
|
1974
|
+
if (diffInSeconds < 3600) {
|
|
1975
|
+
return labels.minutesAgo.replace("{count}", String(Math.floor(diffInSeconds / 60)));
|
|
1976
|
+
}
|
|
1977
|
+
if (diffInSeconds < 86400) {
|
|
1978
|
+
return labels.hoursAgo.replace("{count}", String(Math.floor(diffInSeconds / 3600)));
|
|
1979
|
+
}
|
|
1980
|
+
if (diffInSeconds < 604800) {
|
|
1981
|
+
return labels.daysAgo.replace("{count}", String(Math.floor(diffInSeconds / 86400)));
|
|
1982
|
+
}
|
|
1983
|
+
return m.format("MMM D, YYYY");
|
|
1984
|
+
}
|
|
1985
|
+
function isSameDay(date1, date2) {
|
|
1986
|
+
if (!date1 || !date2) return false;
|
|
1987
|
+
return moment.utc(date1).format("YYYY-MM-DD") === moment.utc(date2).format("YYYY-MM-DD");
|
|
1988
|
+
}
|
|
1989
|
+
function formatTicketDate(date) {
|
|
1990
|
+
if (!date) return "";
|
|
1991
|
+
return moment.utc(date).local().format("MMM D, YYYY");
|
|
1992
|
+
}
|
|
1957
1993
|
function TicketItem({ ticket, onClick }) {
|
|
1958
1994
|
const st = useSupportT();
|
|
1959
1995
|
const labels = useMemo(() => ({
|
|
@@ -1971,49 +2007,37 @@ function TicketItem({ ticket, onClick }) {
|
|
|
1971
2007
|
daysAgo: st("time.daysAgo")
|
|
1972
2008
|
}
|
|
1973
2009
|
}), [st]);
|
|
1974
|
-
const
|
|
1975
|
-
|
|
1976
|
-
const m = moment2.utc(date).local();
|
|
1977
|
-
const now = moment2();
|
|
1978
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
1979
|
-
if (diffInSeconds < 60) return labels.time.justNow;
|
|
1980
|
-
if (diffInSeconds < 3600) return labels.time.minutesAgo.replace("{count}", String(Math.floor(diffInSeconds / 60)));
|
|
1981
|
-
if (diffInSeconds < 86400) return labels.time.hoursAgo.replace("{count}", String(Math.floor(diffInSeconds / 3600)));
|
|
1982
|
-
if (diffInSeconds < 604800) return labels.time.daysAgo.replace("{count}", String(Math.floor(diffInSeconds / 86400)));
|
|
1983
|
-
return m.format("MMM D, YYYY");
|
|
2010
|
+
const getRelativeTime = useCallback((date) => {
|
|
2011
|
+
return formatRelativeTime(date, labels.time);
|
|
1984
2012
|
}, [labels.time]);
|
|
1985
2013
|
const statusLabel = labels.status[ticket.status] || ticket.status || labels.status.open;
|
|
2014
|
+
const statusConfig = getStatusConfig(ticket.status || "open");
|
|
1986
2015
|
const hasUnread = (ticket.unanswered_messages_count || 0) > 0;
|
|
1987
2016
|
return /* @__PURE__ */ jsxs(
|
|
1988
|
-
"
|
|
2017
|
+
"button",
|
|
1989
2018
|
{
|
|
2019
|
+
type: "button",
|
|
1990
2020
|
className: cn(
|
|
1991
|
-
"
|
|
1992
|
-
"
|
|
1993
|
-
"hover:bg-accent/50"
|
|
1994
|
-
"active:scale-[0.98]",
|
|
1995
|
-
hasUnread && "bg-primary/5"
|
|
2021
|
+
"w-full flex items-start gap-3 p-4 text-left",
|
|
2022
|
+
"transition-colors duration-150",
|
|
2023
|
+
"hover:bg-accent/50 active:bg-accent"
|
|
1996
2024
|
),
|
|
1997
2025
|
onClick,
|
|
1998
2026
|
children: [
|
|
1999
|
-
/* @__PURE__ */ jsx("div", { className: "w-2
|
|
2027
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 pt-1.5 shrink-0", children: hasUnread && /* @__PURE__ */ jsx("div", { className: "w-2 h-2 rounded-full bg-blue-500" }) }),
|
|
2000
2028
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2001
|
-
/* @__PURE__ */
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2011
|
-
/* @__PURE__ */ jsx(Clock, { className: "h-3 w-3" }),
|
|
2012
|
-
/* @__PURE__ */ jsx("span", { children: formatRelativeTime(ticket.created_at) })
|
|
2029
|
+
/* @__PURE__ */ jsx("h3", { className: cn(
|
|
2030
|
+
"text-[15px] line-clamp-1",
|
|
2031
|
+
hasUnread ? "font-semibold" : "font-medium"
|
|
2032
|
+
), children: ticket.subject }),
|
|
2033
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [
|
|
2034
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[13px]", statusConfig.color), children: statusLabel }),
|
|
2035
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[13px] text-muted-foreground", children: [
|
|
2036
|
+
"\xB7 ",
|
|
2037
|
+
getRelativeTime(ticket.created_at)
|
|
2013
2038
|
] })
|
|
2014
2039
|
] })
|
|
2015
|
-
] })
|
|
2016
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5 text-muted-foreground/50 group-hover:text-muted-foreground transition-colors flex-shrink-0" })
|
|
2040
|
+
] })
|
|
2017
2041
|
]
|
|
2018
2042
|
}
|
|
2019
2043
|
);
|
|
@@ -2058,24 +2082,23 @@ function TicketList({ onTicketClick, className }) {
|
|
|
2058
2082
|
};
|
|
2059
2083
|
}, [hasMoreTickets, isLoadingMoreTickets, loadMoreTickets]);
|
|
2060
2084
|
if (isLoadingTickets) {
|
|
2061
|
-
return /* @__PURE__ */ jsx("div", { className: cn("px-4 py-6
|
|
2085
|
+
return /* @__PURE__ */ jsx("div", { className: cn("px-4 py-6", className), children: /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/50", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx("div", { className: "py-4", children: /* @__PURE__ */ jsx(
|
|
2062
2086
|
Skeleton,
|
|
2063
2087
|
{
|
|
2064
|
-
className: "h-
|
|
2088
|
+
className: "h-12 w-full",
|
|
2065
2089
|
style: { animationDelay: `${i * 100}ms` }
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2068
|
-
)) });
|
|
2090
|
+
}
|
|
2091
|
+
) }, i)) }) });
|
|
2069
2092
|
}
|
|
2070
2093
|
if (!tickets || tickets.length === 0) {
|
|
2071
|
-
return /* @__PURE__ */ jsxs(
|
|
2072
|
-
/* @__PURE__ */ jsx(
|
|
2073
|
-
/* @__PURE__ */ jsx(
|
|
2074
|
-
/* @__PURE__ */ jsx(
|
|
2094
|
+
return /* @__PURE__ */ jsxs(Empty, { className: cn("py-16", className), children: [
|
|
2095
|
+
/* @__PURE__ */ jsx(EmptyMedia, { variant: "icon", children: /* @__PURE__ */ jsx(MessageSquare, { className: "h-8 w-8" }) }),
|
|
2096
|
+
/* @__PURE__ */ jsx(EmptyTitle, { children: labels.noTickets }),
|
|
2097
|
+
/* @__PURE__ */ jsx(EmptyDescription, { children: labels.noTicketsDescription })
|
|
2075
2098
|
] });
|
|
2076
2099
|
}
|
|
2077
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("px-4 py-
|
|
2078
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2100
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("px-4 py-2", className), children: [
|
|
2101
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/50", children: tickets.map((ticket) => /* @__PURE__ */ jsx(
|
|
2079
2102
|
TicketItem,
|
|
2080
2103
|
{
|
|
2081
2104
|
ticket,
|
|
@@ -2105,49 +2128,70 @@ function TicketList({ onTicketClick, className }) {
|
|
|
2105
2128
|
) })
|
|
2106
2129
|
] });
|
|
2107
2130
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
return "outline";
|
|
2126
|
-
case "closed":
|
|
2127
|
-
return "secondary";
|
|
2128
|
-
default:
|
|
2129
|
-
return "default";
|
|
2131
|
+
function groupMessages(messages, currentUserId) {
|
|
2132
|
+
const groups = [];
|
|
2133
|
+
let currentGroup = null;
|
|
2134
|
+
for (const msg of messages) {
|
|
2135
|
+
const isFromUser = msg.sender?.id && currentUserId && String(msg.sender.id) === String(currentUserId) || msg.is_from_author;
|
|
2136
|
+
const senderId = msg.sender?.id || null;
|
|
2137
|
+
const shouldStartNewGroup = !currentGroup || currentGroup.isFromUser !== isFromUser || currentGroup.senderId !== senderId;
|
|
2138
|
+
if (shouldStartNewGroup) {
|
|
2139
|
+
currentGroup = {
|
|
2140
|
+
senderId,
|
|
2141
|
+
isFromUser: !!isFromUser,
|
|
2142
|
+
messages: [msg]
|
|
2143
|
+
};
|
|
2144
|
+
groups.push(currentGroup);
|
|
2145
|
+
} else {
|
|
2146
|
+
currentGroup.messages.push(msg);
|
|
2147
|
+
}
|
|
2130
2148
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
2149
|
+
return groups;
|
|
2150
|
+
}
|
|
2151
|
+
var DateSeparator = ({ date }) => /* @__PURE__ */ jsx("div", { className: "flex justify-center my-4", children: /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground bg-muted/60 px-3 py-1 rounded-full", children: formatDateSeparator(date) }) });
|
|
2152
|
+
var MessageBubble = ({
|
|
2153
|
+
message,
|
|
2154
|
+
isFromUser,
|
|
2155
|
+
showAvatar,
|
|
2156
|
+
showTimestamp,
|
|
2157
|
+
currentUser,
|
|
2158
|
+
labels
|
|
2159
|
+
}) => {
|
|
2133
2160
|
const sender = message.sender;
|
|
2134
2161
|
const senderInitial = sender?.display_username?.charAt(0)?.toUpperCase() || sender?.initials || "S";
|
|
2135
2162
|
const userInitial = currentUser?.display_username?.charAt(0)?.toUpperCase() || currentUser?.email?.charAt(0)?.toUpperCase() || currentUser?.initials || null;
|
|
2136
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-
|
|
2137
|
-
!isFromUser && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8
|
|
2138
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2163
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-2", isFromUser ? "justify-end" : "justify-start"), children: [
|
|
2164
|
+
!isFromUser && /* @__PURE__ */ jsx("div", { className: "w-8 shrink-0", children: showAvatar && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8", children: sender?.avatar ? /* @__PURE__ */ jsx(AvatarImage, { src: sender.avatar, alt: sender.display_username || labels.supportTeam }) : /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-primary text-primary-foreground text-xs", children: sender?.is_staff ? /* @__PURE__ */ jsx(Headphones, { className: "h-4 w-4" }) : senderInitial }) }) }),
|
|
2165
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-0.5 max-w-[85%]", isFromUser ? "items-end" : "items-start"), children: [
|
|
2166
|
+
/* @__PURE__ */ jsx(
|
|
2167
|
+
"div",
|
|
2168
|
+
{
|
|
2169
|
+
className: cn(
|
|
2170
|
+
"px-4 py-2.5 rounded-[20px]",
|
|
2171
|
+
isFromUser ? "bg-blue-500 text-white" : "bg-[#e9e9eb] dark:bg-zinc-800 text-foreground"
|
|
2172
|
+
),
|
|
2173
|
+
children: /* @__PURE__ */ jsx("p", { className: "text-[15px] leading-relaxed whitespace-pre-wrap break-words", children: message.text })
|
|
2174
|
+
}
|
|
2175
|
+
),
|
|
2176
|
+
showTimestamp && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground px-2 mt-0.5", children: formatMessageTime(message.created_at) })
|
|
2147
2177
|
] }),
|
|
2148
|
-
isFromUser && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8
|
|
2178
|
+
isFromUser && /* @__PURE__ */ jsx("div", { className: "w-8 shrink-0", children: showAvatar && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8", children: currentUser?.avatar ? /* @__PURE__ */ jsx(AvatarImage, { src: currentUser.avatar, alt: currentUser.display_username || currentUser.email || "You" }) : /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-blue-500 text-white text-xs font-medium", children: userInitial || /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }) }) }) })
|
|
2149
2179
|
] });
|
|
2150
2180
|
};
|
|
2181
|
+
var MessageGroupComponent = ({ group, currentUser, labels }) => {
|
|
2182
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.messages.map((msg, idx) => /* @__PURE__ */ jsx(
|
|
2183
|
+
MessageBubble,
|
|
2184
|
+
{
|
|
2185
|
+
message: msg,
|
|
2186
|
+
isFromUser: group.isFromUser,
|
|
2187
|
+
showAvatar: idx === 0,
|
|
2188
|
+
showTimestamp: idx === group.messages.length - 1,
|
|
2189
|
+
currentUser,
|
|
2190
|
+
labels
|
|
2191
|
+
},
|
|
2192
|
+
msg.uuid
|
|
2193
|
+
)) });
|
|
2194
|
+
};
|
|
2151
2195
|
function TicketSheet({ ticket, open, onOpenChange }) {
|
|
2152
2196
|
const st = useSupportT();
|
|
2153
2197
|
const { user } = useAuth();
|
|
@@ -2156,6 +2200,7 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2156
2200
|
const [message, setMessage] = useState("");
|
|
2157
2201
|
const [isSending, setIsSending] = useState(false);
|
|
2158
2202
|
const scrollAreaRef = useRef(null);
|
|
2203
|
+
const textareaRef = useRef(null);
|
|
2159
2204
|
const firstRender = useRef(true);
|
|
2160
2205
|
const labels = useMemo(() => ({
|
|
2161
2206
|
noMessages: st("messageList.noMessages"),
|
|
@@ -2187,6 +2232,7 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2187
2232
|
refresh: refreshMessages,
|
|
2188
2233
|
addOptimistic
|
|
2189
2234
|
} = useMessages(ticket?.uuid || null);
|
|
2235
|
+
const messageGroups = useMemo(() => groupMessages(messages, user?.id), [messages, user?.id]);
|
|
2190
2236
|
useEffect(() => {
|
|
2191
2237
|
firstRender.current = true;
|
|
2192
2238
|
}, [ticket?.uuid]);
|
|
@@ -2199,6 +2245,14 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2199
2245
|
firstRender.current = false;
|
|
2200
2246
|
}
|
|
2201
2247
|
}, [messages]);
|
|
2248
|
+
const handleTextareaChange = useCallback((e) => {
|
|
2249
|
+
setMessage(e.target.value);
|
|
2250
|
+
const textarea = textareaRef.current;
|
|
2251
|
+
if (textarea) {
|
|
2252
|
+
textarea.style.height = "auto";
|
|
2253
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
|
|
2254
|
+
}
|
|
2255
|
+
}, []);
|
|
2202
2256
|
const handleSend = async (e) => {
|
|
2203
2257
|
e.preventDefault();
|
|
2204
2258
|
if (!message.trim() || !ticket?.uuid) return;
|
|
@@ -2224,6 +2278,9 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2224
2278
|
addOptimistic(optimisticMessage);
|
|
2225
2279
|
await sendMessage({ ticketUuid: ticket.uuid, text: messageText });
|
|
2226
2280
|
setMessage("");
|
|
2281
|
+
if (textareaRef.current) {
|
|
2282
|
+
textareaRef.current.style.height = "auto";
|
|
2283
|
+
}
|
|
2227
2284
|
await refreshMessages();
|
|
2228
2285
|
const scrollContainer = scrollAreaRef.current?.querySelector("[data-radix-scroll-area-viewport]");
|
|
2229
2286
|
if (scrollContainer) {
|
|
@@ -2257,32 +2314,61 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2257
2314
|
}, [loadMore]);
|
|
2258
2315
|
const canSendMessage = ticket?.status !== "closed";
|
|
2259
2316
|
const statusLabel = ticket ? labels.status[ticket.status] || ticket.status || labels.status.open : "";
|
|
2317
|
+
const statusConfig = getStatusConfig(ticket?.status || "open");
|
|
2318
|
+
const renderMessages = () => {
|
|
2319
|
+
const elements = [];
|
|
2320
|
+
let lastDate = null;
|
|
2321
|
+
for (const group of messageGroups) {
|
|
2322
|
+
const firstMessage = group.messages[0];
|
|
2323
|
+
if (!firstMessage) continue;
|
|
2324
|
+
const messageDate = firstMessage.created_at;
|
|
2325
|
+
if (!lastDate || !isSameDay(lastDate, messageDate)) {
|
|
2326
|
+
elements.push(
|
|
2327
|
+
/* @__PURE__ */ jsx(DateSeparator, { date: messageDate || "" }, `date-${messageDate}`)
|
|
2328
|
+
);
|
|
2329
|
+
lastDate = messageDate || null;
|
|
2330
|
+
}
|
|
2331
|
+
elements.push(
|
|
2332
|
+
/* @__PURE__ */ jsx(
|
|
2333
|
+
MessageGroupComponent,
|
|
2334
|
+
{
|
|
2335
|
+
group,
|
|
2336
|
+
currentUser: user,
|
|
2337
|
+
labels: { supportTeam: labels.supportTeam, staff: labels.staff }
|
|
2338
|
+
},
|
|
2339
|
+
`group-${firstMessage.uuid}`
|
|
2340
|
+
)
|
|
2341
|
+
);
|
|
2342
|
+
}
|
|
2343
|
+
return elements;
|
|
2344
|
+
};
|
|
2260
2345
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-xl p-0 flex flex-col h-full", children: [
|
|
2261
2346
|
/* @__PURE__ */ jsx(ResponsiveSheetHeader, { className: "px-6 py-4 border-b flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2262
2347
|
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { className: "text-lg font-semibold line-clamp-2", children: ticket?.subject || "Ticket" }),
|
|
2263
2348
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
2264
|
-
/* @__PURE__ */ jsx(
|
|
2265
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
2349
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[13px] px-2 py-0.5 rounded-full", statusConfig.bg, statusConfig.color), children: statusLabel }),
|
|
2350
|
+
/* @__PURE__ */ jsx("span", { className: "text-[13px] text-muted-foreground", children: formatTicketDate(ticket?.created_at) })
|
|
2266
2351
|
] })
|
|
2267
2352
|
] }) }) }),
|
|
2268
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: isLoadingMessages ? /* @__PURE__ */ jsx("div", { className: "p-6 space-y-4", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs("div", { className: "flex gap-
|
|
2269
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full" }),
|
|
2270
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-16
|
|
2353
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: isLoadingMessages ? /* @__PURE__ */ jsx("div", { className: "p-6 space-y-4", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs("div", { className: cn("flex gap-2", i % 2 === 0 ? "justify-end" : "justify-start"), children: [
|
|
2354
|
+
i % 2 !== 0 && /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
|
|
2355
|
+
/* @__PURE__ */ jsx(Skeleton, { className: cn("h-16 rounded-[20px]", i % 2 === 0 ? "w-[60%]" : "w-[70%]") }),
|
|
2356
|
+
i % 2 === 0 && /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
|
|
2271
2357
|
] }, i)) }) : messages.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center", children: [
|
|
2272
|
-
/* @__PURE__ */ jsx(MessageSquare, { className: "h-
|
|
2358
|
+
/* @__PURE__ */ jsx("div", { className: "h-16 w-16 mx-auto mb-4 bg-muted rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx(MessageSquare, { className: "h-8 w-8 text-muted-foreground" }) }),
|
|
2273
2359
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: labels.noMessages }),
|
|
2274
2360
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: labels.noMessagesDescription })
|
|
2275
|
-
] }) : /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxs("div", { className: "p-
|
|
2361
|
+
] }) : /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-3", children: [
|
|
2276
2362
|
hasMore && /* @__PURE__ */ jsx("div", { className: "flex justify-center pb-4", children: isLoadingMore ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
2277
2363
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2278
2364
|
/* @__PURE__ */ jsx("span", { className: "text-sm", children: labels.loadingOlder })
|
|
2279
2365
|
] }) : /* @__PURE__ */ jsxs(
|
|
2280
2366
|
Button,
|
|
2281
2367
|
{
|
|
2282
|
-
variant: "
|
|
2368
|
+
variant: "ghost",
|
|
2283
2369
|
size: "sm",
|
|
2284
2370
|
onClick: handleLoadMore,
|
|
2285
|
-
className: "text-xs",
|
|
2371
|
+
className: "text-xs text-muted-foreground",
|
|
2286
2372
|
children: [
|
|
2287
2373
|
labels.loadOlder,
|
|
2288
2374
|
" (",
|
|
@@ -2291,59 +2377,44 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2291
2377
|
]
|
|
2292
2378
|
}
|
|
2293
2379
|
) }),
|
|
2294
|
-
|
|
2295
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2296
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(messages[0]?.created_at) }),
|
|
2297
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2298
|
-
] }),
|
|
2299
|
-
messages.map((msg, index) => {
|
|
2300
|
-
const isFromUser = msg.sender?.id && user?.id && String(msg.sender.id) === String(user.id) || msg.sender?.email && user?.email && msg.sender.email === user.email || msg.is_from_author && ticket?.user && user?.id && String(ticket.user) === String(user.id);
|
|
2301
|
-
const previousMessage = index > 0 ? messages[index - 1] : null;
|
|
2302
|
-
const showDateSeparator = previousMessage && moment2.utc(previousMessage.created_at || "").format("YYYY-MM-DD") !== moment2.utc(msg.created_at || "").format("YYYY-MM-DD");
|
|
2303
|
-
return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
2304
|
-
showDateSeparator && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 my-4", children: [
|
|
2305
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2306
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(msg.created_at) }),
|
|
2307
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2308
|
-
] }),
|
|
2309
|
-
/* @__PURE__ */ jsx(
|
|
2310
|
-
MessageBubble,
|
|
2311
|
-
{
|
|
2312
|
-
message: msg,
|
|
2313
|
-
isFromUser: !!isFromUser,
|
|
2314
|
-
currentUser: user,
|
|
2315
|
-
labels: { supportTeam: labels.supportTeam, staff: labels.staff }
|
|
2316
|
-
}
|
|
2317
|
-
)
|
|
2318
|
-
] }, msg.uuid);
|
|
2319
|
-
})
|
|
2380
|
+
renderMessages()
|
|
2320
2381
|
] }) }) }),
|
|
2321
|
-
/* @__PURE__ */
|
|
2322
|
-
/* @__PURE__ */
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2382
|
+
/* @__PURE__ */ jsx("form", { onSubmit: handleSend, className: "p-3 border-t bg-background/95 backdrop-blur flex-shrink-0", children: canSendMessage ? /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2 bg-muted/50 rounded-[24px] px-4 py-2", children: [
|
|
2383
|
+
/* @__PURE__ */ jsx(
|
|
2384
|
+
"textarea",
|
|
2385
|
+
{
|
|
2386
|
+
ref: textareaRef,
|
|
2387
|
+
value: message,
|
|
2388
|
+
onChange: handleTextareaChange,
|
|
2389
|
+
onKeyDown: handleKeyDown,
|
|
2390
|
+
placeholder: labels.placeholder,
|
|
2391
|
+
className: cn(
|
|
2392
|
+
"flex-1 bg-transparent border-none resize-none",
|
|
2393
|
+
"text-[15px] placeholder:text-muted-foreground",
|
|
2394
|
+
"min-h-[24px] max-h-[120px] focus:outline-none"
|
|
2395
|
+
),
|
|
2396
|
+
rows: 1,
|
|
2397
|
+
disabled: isSending
|
|
2398
|
+
}
|
|
2399
|
+
),
|
|
2400
|
+
/* @__PURE__ */ jsx(
|
|
2401
|
+
Button,
|
|
2402
|
+
{
|
|
2403
|
+
type: "submit",
|
|
2404
|
+
size: "icon",
|
|
2405
|
+
variant: "ghost",
|
|
2406
|
+
className: cn(
|
|
2407
|
+
"rounded-full h-8 w-8 shrink-0",
|
|
2408
|
+
message.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : ""
|
|
2409
|
+
),
|
|
2410
|
+
disabled: !message.trim() || isSending,
|
|
2411
|
+
children: isSending ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4" })
|
|
2412
|
+
}
|
|
2413
|
+
)
|
|
2414
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-2", children: [
|
|
2415
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: labels.ticketClosed }),
|
|
2416
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: labels.ticketClosedDescription })
|
|
2417
|
+
] }) })
|
|
2347
2418
|
] }) });
|
|
2348
2419
|
}
|
|
2349
2420
|
function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
@@ -2404,13 +2475,10 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2404
2475
|
};
|
|
2405
2476
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
2406
2477
|
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2407
|
-
/* @__PURE__ */
|
|
2408
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-5 w-5" }),
|
|
2409
|
-
labels.title
|
|
2410
|
-
] }),
|
|
2478
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: labels.title }),
|
|
2411
2479
|
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: labels.description })
|
|
2412
2480
|
] }),
|
|
2413
|
-
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-
|
|
2481
|
+
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-5 mt-4", children: [
|
|
2414
2482
|
/* @__PURE__ */ jsx(
|
|
2415
2483
|
FormField,
|
|
2416
2484
|
{
|
|
@@ -2450,7 +2518,7 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2450
2518
|
] })
|
|
2451
2519
|
}
|
|
2452
2520
|
),
|
|
2453
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-
|
|
2521
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-2", children: [
|
|
2454
2522
|
/* @__PURE__ */ jsx(
|
|
2455
2523
|
Button,
|
|
2456
2524
|
{
|
|
@@ -2464,10 +2532,7 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2464
2532
|
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2465
2533
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2466
2534
|
labels.creating
|
|
2467
|
-
] }) :
|
|
2468
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
2469
|
-
labels.create
|
|
2470
|
-
] }) })
|
|
2535
|
+
] }) : labels.create })
|
|
2471
2536
|
] })
|
|
2472
2537
|
] }) })
|
|
2473
2538
|
] }) });
|
|
@@ -2538,7 +2603,7 @@ function SupportPage({ isDemo = false }) {
|
|
|
2538
2603
|
// package.json
|
|
2539
2604
|
var package_default = {
|
|
2540
2605
|
name: "@djangocfg/ext-support",
|
|
2541
|
-
version: "1.0.
|
|
2606
|
+
version: "1.0.26",
|
|
2542
2607
|
description: "Support ticket system extension for DjangoCFG",
|
|
2543
2608
|
keywords: [
|
|
2544
2609
|
"django",
|