@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/hooks.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 useSWR, { 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 = client || 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 = client || 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) {
|
|
@@ -2049,78 +2033,6 @@ var en = {
|
|
|
2049
2033
|
}
|
|
2050
2034
|
};
|
|
2051
2035
|
|
|
2052
|
-
// src/i18n/locales/ru.ts
|
|
2053
|
-
var ru = {
|
|
2054
|
-
layout: {
|
|
2055
|
-
title: "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
2056
|
-
titleShort: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430",
|
|
2057
|
-
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",
|
|
2058
|
-
newTicket: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
2059
|
-
},
|
|
2060
|
-
hero: {
|
|
2061
|
-
openTickets: "\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
2062
|
-
unreadMessages: "\u041D\u0435\u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445"
|
|
2063
|
-
},
|
|
2064
|
-
status: {
|
|
2065
|
-
open: "\u041E\u0442\u043A\u0440\u044B\u0442",
|
|
2066
|
-
waitingForUser: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0430\u0441",
|
|
2067
|
-
waitingForAdmin: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0443",
|
|
2068
|
-
resolved: "\u0420\u0435\u0448\u0451\u043D",
|
|
2069
|
-
closed: "\u0417\u0430\u043A\u0440\u044B\u0442"
|
|
2070
|
-
},
|
|
2071
|
-
ticketList: {
|
|
2072
|
-
noTickets: "\u041D\u0435\u0442 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
2073
|
-
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",
|
|
2074
|
-
loadingMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430...",
|
|
2075
|
-
loadMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0451",
|
|
2076
|
-
allLoaded: "\u0412\u0441\u0435 {count} \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E"
|
|
2077
|
-
},
|
|
2078
|
-
createTicket: {
|
|
2079
|
-
title: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
2080
|
-
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",
|
|
2081
|
-
subjectLabel: "\u0422\u0435\u043C\u0430",
|
|
2082
|
-
subjectPlaceholder: "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B",
|
|
2083
|
-
messageLabel: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
2084
|
-
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...",
|
|
2085
|
-
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
2086
|
-
creating: "\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435...",
|
|
2087
|
-
create: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
2088
|
-
},
|
|
2089
|
-
validation: {
|
|
2090
|
-
subjectRequired: "\u0422\u0435\u043C\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u0430",
|
|
2091
|
-
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)",
|
|
2092
|
-
messageRequired: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E",
|
|
2093
|
-
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)"
|
|
2094
|
-
},
|
|
2095
|
-
messages: {
|
|
2096
|
-
ticketCreated: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u043E",
|
|
2097
|
-
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",
|
|
2098
|
-
messageSent: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
2099
|
-
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"
|
|
2100
|
-
},
|
|
2101
|
-
messageInput: {
|
|
2102
|
-
placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435...",
|
|
2103
|
-
ticketClosed: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E",
|
|
2104
|
-
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."
|
|
2105
|
-
},
|
|
2106
|
-
messageList: {
|
|
2107
|
-
noTicketSelected: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E",
|
|
2108
|
-
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",
|
|
2109
|
-
noMessages: "\u041D\u0435\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
2110
|
-
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",
|
|
2111
|
-
loadingOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u0442\u0430\u0440\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439...",
|
|
2112
|
-
loadOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u0442\u0430\u0440\u044B\u0435",
|
|
2113
|
-
supportTeam: "\u0421\u043B\u0443\u0436\u0431\u0430 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
2114
|
-
staff: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A"
|
|
2115
|
-
},
|
|
2116
|
-
time: {
|
|
2117
|
-
justNow: "\u0422\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E",
|
|
2118
|
-
minutesAgo: "{count} \u043C\u0438\u043D \u043D\u0430\u0437\u0430\u0434",
|
|
2119
|
-
hoursAgo: "{count}\u0447 \u043D\u0430\u0437\u0430\u0434",
|
|
2120
|
-
daysAgo: "{count}\u0434 \u043D\u0430\u0437\u0430\u0434"
|
|
2121
|
-
}
|
|
2122
|
-
};
|
|
2123
|
-
|
|
2124
2036
|
// src/i18n/locales/ko.ts
|
|
2125
2037
|
var ko = {
|
|
2126
2038
|
layout: {
|
|
@@ -2193,6 +2105,78 @@ var ko = {
|
|
|
2193
2105
|
}
|
|
2194
2106
|
};
|
|
2195
2107
|
|
|
2108
|
+
// src/i18n/locales/ru.ts
|
|
2109
|
+
var ru = {
|
|
2110
|
+
layout: {
|
|
2111
|
+
title: "\u0426\u0435\u043D\u0442\u0440 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
2112
|
+
titleShort: "\u041F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430",
|
|
2113
|
+
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",
|
|
2114
|
+
newTicket: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
2115
|
+
},
|
|
2116
|
+
hero: {
|
|
2117
|
+
openTickets: "\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
2118
|
+
unreadMessages: "\u041D\u0435\u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445"
|
|
2119
|
+
},
|
|
2120
|
+
status: {
|
|
2121
|
+
open: "\u041E\u0442\u043A\u0440\u044B\u0442",
|
|
2122
|
+
waitingForUser: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u0432\u0430\u0441",
|
|
2123
|
+
waitingForAdmin: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0443",
|
|
2124
|
+
resolved: "\u0420\u0435\u0448\u0451\u043D",
|
|
2125
|
+
closed: "\u0417\u0430\u043A\u0440\u044B\u0442"
|
|
2126
|
+
},
|
|
2127
|
+
ticketList: {
|
|
2128
|
+
noTickets: "\u041D\u0435\u0442 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439",
|
|
2129
|
+
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",
|
|
2130
|
+
loadingMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430...",
|
|
2131
|
+
loadMore: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0449\u0451",
|
|
2132
|
+
allLoaded: "\u0412\u0441\u0435 {count} \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u043E"
|
|
2133
|
+
},
|
|
2134
|
+
createTicket: {
|
|
2135
|
+
title: "\u041D\u043E\u0432\u043E\u0435 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435",
|
|
2136
|
+
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",
|
|
2137
|
+
subjectLabel: "\u0422\u0435\u043C\u0430",
|
|
2138
|
+
subjectPlaceholder: "\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B",
|
|
2139
|
+
messageLabel: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435",
|
|
2140
|
+
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...",
|
|
2141
|
+
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
2142
|
+
creating: "\u0421\u043E\u0437\u0434\u0430\u043D\u0438\u0435...",
|
|
2143
|
+
create: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435"
|
|
2144
|
+
},
|
|
2145
|
+
validation: {
|
|
2146
|
+
subjectRequired: "\u0422\u0435\u043C\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u0430",
|
|
2147
|
+
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)",
|
|
2148
|
+
messageRequired: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E",
|
|
2149
|
+
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)"
|
|
2150
|
+
},
|
|
2151
|
+
messages: {
|
|
2152
|
+
ticketCreated: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u043E",
|
|
2153
|
+
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",
|
|
2154
|
+
messageSent: "\u0421\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
2155
|
+
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"
|
|
2156
|
+
},
|
|
2157
|
+
messageInput: {
|
|
2158
|
+
placeholder: "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435...",
|
|
2159
|
+
ticketClosed: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E",
|
|
2160
|
+
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."
|
|
2161
|
+
},
|
|
2162
|
+
messageList: {
|
|
2163
|
+
noTicketSelected: "\u041E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435 \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043D\u043E",
|
|
2164
|
+
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",
|
|
2165
|
+
noMessages: "\u041D\u0435\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
2166
|
+
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",
|
|
2167
|
+
loadingOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u0442\u0430\u0440\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439...",
|
|
2168
|
+
loadOlder: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u0442\u0430\u0440\u044B\u0435",
|
|
2169
|
+
supportTeam: "\u0421\u043B\u0443\u0436\u0431\u0430 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
2170
|
+
staff: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A"
|
|
2171
|
+
},
|
|
2172
|
+
time: {
|
|
2173
|
+
justNow: "\u0422\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E",
|
|
2174
|
+
minutesAgo: "{count} \u043C\u0438\u043D \u043D\u0430\u0437\u0430\u0434",
|
|
2175
|
+
hoursAgo: "{count}\u0447 \u043D\u0430\u0437\u0430\u0434",
|
|
2176
|
+
daysAgo: "{count}\u0434 \u043D\u0430\u0437\u0430\u0434"
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
|
|
2196
2180
|
// src/i18n/useSupportT.ts
|
|
2197
2181
|
var translations = { en, ru, ko };
|
|
2198
2182
|
function getNestedValue(obj, path) {
|
|
@@ -2226,27 +2210,22 @@ function SupportHero({ onCreateTicket, className }) {
|
|
|
2226
2210
|
unreadMessages: st("hero.unreadMessages")
|
|
2227
2211
|
}), [st]);
|
|
2228
2212
|
const openTicketsCount = tickets.filter((t) => t.status !== "closed" && t.status !== "resolved").length;
|
|
2229
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center py-
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-
|
|
2232
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
/* @__PURE__ */ jsx("
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2240
|
-
/* @__PURE__ */ jsxs(
|
|
2213
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center py-12 px-4", className), children: [
|
|
2214
|
+
isLoadingTickets ? /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2215
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-48 mx-auto mb-2" }),
|
|
2216
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-64 mx-auto" })
|
|
2217
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2218
|
+
/* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold tracking-tight", children: labels.title }),
|
|
2219
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg text-muted-foreground mt-2", children: labels.subtitle })
|
|
2220
|
+
] }),
|
|
2221
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mt-6", children: [
|
|
2222
|
+
/* @__PURE__ */ jsx(
|
|
2241
2223
|
Button,
|
|
2242
2224
|
{
|
|
2243
2225
|
size: "lg",
|
|
2244
2226
|
onClick: onCreateTicket,
|
|
2245
|
-
className: "rounded-full px-
|
|
2246
|
-
children:
|
|
2247
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-5 w-5 mr-2" }),
|
|
2248
|
-
labels.newTicket
|
|
2249
|
-
]
|
|
2227
|
+
className: "rounded-full px-8 h-12 text-base",
|
|
2228
|
+
children: labels.newTicket
|
|
2250
2229
|
}
|
|
2251
2230
|
),
|
|
2252
2231
|
/* @__PURE__ */ jsx(
|
|
@@ -2255,43 +2234,100 @@ function SupportHero({ onCreateTicket, className }) {
|
|
|
2255
2234
|
size: "icon",
|
|
2256
2235
|
variant: "ghost",
|
|
2257
2236
|
onClick: () => refreshTickets(),
|
|
2258
|
-
className: "rounded-full",
|
|
2237
|
+
className: "rounded-full h-10 w-10",
|
|
2259
2238
|
children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" })
|
|
2260
2239
|
}
|
|
2261
2240
|
)
|
|
2262
2241
|
] }),
|
|
2263
|
-
!isLoadingTickets && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
2264
|
-
/* @__PURE__ */ jsxs("
|
|
2265
|
-
|
|
2266
|
-
|
|
2242
|
+
!isLoadingTickets && (openTicketsCount > 0 || unreadCount > 0) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-4", children: [
|
|
2243
|
+
openTicketsCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground bg-muted px-3 py-1 rounded-full", children: [
|
|
2244
|
+
openTicketsCount,
|
|
2245
|
+
" ",
|
|
2246
|
+
labels.openTickets.toLowerCase()
|
|
2267
2247
|
] }),
|
|
2268
|
-
/* @__PURE__ */
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
unreadCount > 0 ? "text-destructive" : "text-foreground"
|
|
2273
|
-
), children: unreadCount }),
|
|
2274
|
-
/* @__PURE__ */ jsx("span", { children: labels.unreadMessages })
|
|
2248
|
+
unreadCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-sm text-destructive bg-destructive/10 px-3 py-1 rounded-full", children: [
|
|
2249
|
+
unreadCount,
|
|
2250
|
+
" ",
|
|
2251
|
+
labels.unreadMessages.toLowerCase()
|
|
2275
2252
|
] })
|
|
2276
2253
|
] })
|
|
2277
2254
|
] });
|
|
2278
2255
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2256
|
+
|
|
2257
|
+
// src/utils/status.ts
|
|
2258
|
+
var ticketStatusConfig = {
|
|
2259
|
+
open: {
|
|
2260
|
+
color: "text-blue-600 dark:text-blue-400",
|
|
2261
|
+
bg: "bg-blue-500/10"
|
|
2262
|
+
},
|
|
2263
|
+
waiting_for_user: {
|
|
2264
|
+
color: "text-orange-600 dark:text-orange-400",
|
|
2265
|
+
bg: "bg-orange-500/10"
|
|
2266
|
+
},
|
|
2267
|
+
waiting_for_admin: {
|
|
2268
|
+
color: "text-muted-foreground",
|
|
2269
|
+
bg: "bg-muted"
|
|
2270
|
+
},
|
|
2271
|
+
resolved: {
|
|
2272
|
+
color: "text-green-600 dark:text-green-400",
|
|
2273
|
+
bg: "bg-green-500/10"
|
|
2274
|
+
},
|
|
2275
|
+
closed: {
|
|
2276
|
+
color: "text-muted-foreground",
|
|
2277
|
+
bg: "bg-muted"
|
|
2293
2278
|
}
|
|
2294
2279
|
};
|
|
2280
|
+
function getStatusConfig(status) {
|
|
2281
|
+
return ticketStatusConfig[status] || ticketStatusConfig.open;
|
|
2282
|
+
}
|
|
2283
|
+
function formatMessageTime(date) {
|
|
2284
|
+
if (!date) return "";
|
|
2285
|
+
return moment.utc(date).local().format("h:mm A");
|
|
2286
|
+
}
|
|
2287
|
+
function formatDateSeparator(date) {
|
|
2288
|
+
if (!date) return "";
|
|
2289
|
+
const m = moment.utc(date).local();
|
|
2290
|
+
const now = moment();
|
|
2291
|
+
const today = now.clone().startOf("day");
|
|
2292
|
+
const yesterday = now.clone().subtract(1, "day").startOf("day");
|
|
2293
|
+
if (m.isSame(today, "day")) {
|
|
2294
|
+
return "Today";
|
|
2295
|
+
}
|
|
2296
|
+
if (m.isSame(yesterday, "day")) {
|
|
2297
|
+
return "Yesterday";
|
|
2298
|
+
}
|
|
2299
|
+
if (m.isSame(now, "year")) {
|
|
2300
|
+
return m.format("MMM D");
|
|
2301
|
+
}
|
|
2302
|
+
return m.format("MMM D, YYYY");
|
|
2303
|
+
}
|
|
2304
|
+
function formatRelativeTime(date, labels) {
|
|
2305
|
+
if (!date) return "N/A";
|
|
2306
|
+
const m = moment.utc(date).local();
|
|
2307
|
+
const now = moment();
|
|
2308
|
+
const diffInSeconds = now.diff(m, "seconds");
|
|
2309
|
+
if (diffInSeconds < 60) {
|
|
2310
|
+
return labels.justNow;
|
|
2311
|
+
}
|
|
2312
|
+
if (diffInSeconds < 3600) {
|
|
2313
|
+
return labels.minutesAgo.replace("{count}", String(Math.floor(diffInSeconds / 60)));
|
|
2314
|
+
}
|
|
2315
|
+
if (diffInSeconds < 86400) {
|
|
2316
|
+
return labels.hoursAgo.replace("{count}", String(Math.floor(diffInSeconds / 3600)));
|
|
2317
|
+
}
|
|
2318
|
+
if (diffInSeconds < 604800) {
|
|
2319
|
+
return labels.daysAgo.replace("{count}", String(Math.floor(diffInSeconds / 86400)));
|
|
2320
|
+
}
|
|
2321
|
+
return m.format("MMM D, YYYY");
|
|
2322
|
+
}
|
|
2323
|
+
function isSameDay(date1, date2) {
|
|
2324
|
+
if (!date1 || !date2) return false;
|
|
2325
|
+
return moment.utc(date1).format("YYYY-MM-DD") === moment.utc(date2).format("YYYY-MM-DD");
|
|
2326
|
+
}
|
|
2327
|
+
function formatTicketDate(date) {
|
|
2328
|
+
if (!date) return "";
|
|
2329
|
+
return moment.utc(date).local().format("MMM D, YYYY");
|
|
2330
|
+
}
|
|
2295
2331
|
function TicketItem({ ticket, onClick }) {
|
|
2296
2332
|
const st = useSupportT();
|
|
2297
2333
|
const labels = useMemo(() => ({
|
|
@@ -2309,49 +2345,37 @@ function TicketItem({ ticket, onClick }) {
|
|
|
2309
2345
|
daysAgo: st("time.daysAgo")
|
|
2310
2346
|
}
|
|
2311
2347
|
}), [st]);
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
const m = moment2.utc(date).local();
|
|
2315
|
-
const now = moment2();
|
|
2316
|
-
const diffInSeconds = now.diff(m, "seconds");
|
|
2317
|
-
if (diffInSeconds < 60) return labels.time.justNow;
|
|
2318
|
-
if (diffInSeconds < 3600) return labels.time.minutesAgo.replace("{count}", String(Math.floor(diffInSeconds / 60)));
|
|
2319
|
-
if (diffInSeconds < 86400) return labels.time.hoursAgo.replace("{count}", String(Math.floor(diffInSeconds / 3600)));
|
|
2320
|
-
if (diffInSeconds < 604800) return labels.time.daysAgo.replace("{count}", String(Math.floor(diffInSeconds / 86400)));
|
|
2321
|
-
return m.format("MMM D, YYYY");
|
|
2348
|
+
const getRelativeTime = useCallback((date) => {
|
|
2349
|
+
return formatRelativeTime(date, labels.time);
|
|
2322
2350
|
}, [labels.time]);
|
|
2323
2351
|
const statusLabel = labels.status[ticket.status] || ticket.status || labels.status.open;
|
|
2352
|
+
const statusConfig = getStatusConfig(ticket.status || "open");
|
|
2324
2353
|
const hasUnread = (ticket.unanswered_messages_count || 0) > 0;
|
|
2325
2354
|
return /* @__PURE__ */ jsxs(
|
|
2326
|
-
"
|
|
2355
|
+
"button",
|
|
2327
2356
|
{
|
|
2357
|
+
type: "button",
|
|
2328
2358
|
className: cn(
|
|
2329
|
-
"
|
|
2330
|
-
"
|
|
2331
|
-
"hover:bg-accent/50"
|
|
2332
|
-
"active:scale-[0.98]",
|
|
2333
|
-
hasUnread && "bg-primary/5"
|
|
2359
|
+
"w-full flex items-start gap-3 p-4 text-left",
|
|
2360
|
+
"transition-colors duration-150",
|
|
2361
|
+
"hover:bg-accent/50 active:bg-accent"
|
|
2334
2362
|
),
|
|
2335
2363
|
onClick,
|
|
2336
2364
|
children: [
|
|
2337
|
-
/* @__PURE__ */ jsx("div", { className: "w-2
|
|
2365
|
+
/* @__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" }) }),
|
|
2338
2366
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2349
|
-
/* @__PURE__ */ jsx(Clock, { className: "h-3 w-3" }),
|
|
2350
|
-
/* @__PURE__ */ jsx("span", { children: formatRelativeTime(ticket.created_at) })
|
|
2367
|
+
/* @__PURE__ */ jsx("h3", { className: cn(
|
|
2368
|
+
"text-[15px] line-clamp-1",
|
|
2369
|
+
hasUnread ? "font-semibold" : "font-medium"
|
|
2370
|
+
), children: ticket.subject }),
|
|
2371
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [
|
|
2372
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[13px]", statusConfig.color), children: statusLabel }),
|
|
2373
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[13px] text-muted-foreground", children: [
|
|
2374
|
+
"\xB7 ",
|
|
2375
|
+
getRelativeTime(ticket.created_at)
|
|
2351
2376
|
] })
|
|
2352
2377
|
] })
|
|
2353
|
-
] })
|
|
2354
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5 text-muted-foreground/50 group-hover:text-muted-foreground transition-colors flex-shrink-0" })
|
|
2378
|
+
] })
|
|
2355
2379
|
]
|
|
2356
2380
|
}
|
|
2357
2381
|
);
|
|
@@ -2396,24 +2420,23 @@ function TicketList({ onTicketClick, className }) {
|
|
|
2396
2420
|
};
|
|
2397
2421
|
}, [hasMoreTickets, isLoadingMoreTickets, loadMoreTickets]);
|
|
2398
2422
|
if (isLoadingTickets) {
|
|
2399
|
-
return /* @__PURE__ */ jsx("div", { className: cn("px-4 py-6
|
|
2423
|
+
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(
|
|
2400
2424
|
Skeleton,
|
|
2401
2425
|
{
|
|
2402
|
-
className: "h-
|
|
2426
|
+
className: "h-12 w-full",
|
|
2403
2427
|
style: { animationDelay: `${i * 100}ms` }
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
)) });
|
|
2428
|
+
}
|
|
2429
|
+
) }, i)) }) });
|
|
2407
2430
|
}
|
|
2408
2431
|
if (!tickets || tickets.length === 0) {
|
|
2409
|
-
return /* @__PURE__ */ jsxs(
|
|
2410
|
-
/* @__PURE__ */ jsx(
|
|
2411
|
-
/* @__PURE__ */ jsx(
|
|
2412
|
-
/* @__PURE__ */ jsx(
|
|
2432
|
+
return /* @__PURE__ */ jsxs(Empty, { className: cn("py-16", className), children: [
|
|
2433
|
+
/* @__PURE__ */ jsx(EmptyMedia, { variant: "icon", children: /* @__PURE__ */ jsx(MessageSquare, { className: "h-8 w-8" }) }),
|
|
2434
|
+
/* @__PURE__ */ jsx(EmptyTitle, { children: labels.noTickets }),
|
|
2435
|
+
/* @__PURE__ */ jsx(EmptyDescription, { children: labels.noTicketsDescription })
|
|
2413
2436
|
] });
|
|
2414
2437
|
}
|
|
2415
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("px-4 py-
|
|
2416
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2438
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("px-4 py-2", className), children: [
|
|
2439
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/50", children: tickets.map((ticket) => /* @__PURE__ */ jsx(
|
|
2417
2440
|
TicketItem,
|
|
2418
2441
|
{
|
|
2419
2442
|
ticket,
|
|
@@ -2443,49 +2466,70 @@ function TicketList({ onTicketClick, className }) {
|
|
|
2443
2466
|
) })
|
|
2444
2467
|
] });
|
|
2445
2468
|
}
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
return "outline";
|
|
2464
|
-
case "closed":
|
|
2465
|
-
return "secondary";
|
|
2466
|
-
default:
|
|
2467
|
-
return "default";
|
|
2469
|
+
function groupMessages(messages, currentUserId) {
|
|
2470
|
+
const groups = [];
|
|
2471
|
+
let currentGroup = null;
|
|
2472
|
+
for (const msg of messages) {
|
|
2473
|
+
const isFromUser = msg.sender?.id && currentUserId && String(msg.sender.id) === String(currentUserId) || msg.is_from_author;
|
|
2474
|
+
const senderId = msg.sender?.id || null;
|
|
2475
|
+
const shouldStartNewGroup = !currentGroup || currentGroup.isFromUser !== isFromUser || currentGroup.senderId !== senderId;
|
|
2476
|
+
if (shouldStartNewGroup) {
|
|
2477
|
+
currentGroup = {
|
|
2478
|
+
senderId,
|
|
2479
|
+
isFromUser: !!isFromUser,
|
|
2480
|
+
messages: [msg]
|
|
2481
|
+
};
|
|
2482
|
+
groups.push(currentGroup);
|
|
2483
|
+
} else {
|
|
2484
|
+
currentGroup.messages.push(msg);
|
|
2485
|
+
}
|
|
2468
2486
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2487
|
+
return groups;
|
|
2488
|
+
}
|
|
2489
|
+
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) }) });
|
|
2490
|
+
var MessageBubble = ({
|
|
2491
|
+
message,
|
|
2492
|
+
isFromUser,
|
|
2493
|
+
showAvatar,
|
|
2494
|
+
showTimestamp,
|
|
2495
|
+
currentUser,
|
|
2496
|
+
labels
|
|
2497
|
+
}) => {
|
|
2471
2498
|
const sender = message.sender;
|
|
2472
2499
|
const senderInitial = sender?.display_username?.charAt(0)?.toUpperCase() || sender?.initials || "S";
|
|
2473
2500
|
const userInitial = currentUser?.display_username?.charAt(0)?.toUpperCase() || currentUser?.email?.charAt(0)?.toUpperCase() || currentUser?.initials || null;
|
|
2474
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-
|
|
2475
|
-
!isFromUser && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8
|
|
2476
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2501
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-2", isFromUser ? "justify-end" : "justify-start"), children: [
|
|
2502
|
+
!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 }) }) }),
|
|
2503
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-0.5 max-w-[85%]", isFromUser ? "items-end" : "items-start"), children: [
|
|
2504
|
+
/* @__PURE__ */ jsx(
|
|
2505
|
+
"div",
|
|
2506
|
+
{
|
|
2507
|
+
className: cn(
|
|
2508
|
+
"px-4 py-2.5 rounded-[20px]",
|
|
2509
|
+
isFromUser ? "bg-blue-500 text-white" : "bg-[#e9e9eb] dark:bg-zinc-800 text-foreground"
|
|
2510
|
+
),
|
|
2511
|
+
children: /* @__PURE__ */ jsx("p", { className: "text-[15px] leading-relaxed whitespace-pre-wrap break-words", children: message.text })
|
|
2512
|
+
}
|
|
2513
|
+
),
|
|
2514
|
+
showTimestamp && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground px-2 mt-0.5", children: formatMessageTime(message.created_at) })
|
|
2485
2515
|
] }),
|
|
2486
|
-
isFromUser && /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8
|
|
2516
|
+
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" }) }) }) })
|
|
2487
2517
|
] });
|
|
2488
2518
|
};
|
|
2519
|
+
var MessageGroupComponent = ({ group, currentUser, labels }) => {
|
|
2520
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.messages.map((msg, idx) => /* @__PURE__ */ jsx(
|
|
2521
|
+
MessageBubble,
|
|
2522
|
+
{
|
|
2523
|
+
message: msg,
|
|
2524
|
+
isFromUser: group.isFromUser,
|
|
2525
|
+
showAvatar: idx === 0,
|
|
2526
|
+
showTimestamp: idx === group.messages.length - 1,
|
|
2527
|
+
currentUser,
|
|
2528
|
+
labels
|
|
2529
|
+
},
|
|
2530
|
+
msg.uuid
|
|
2531
|
+
)) });
|
|
2532
|
+
};
|
|
2489
2533
|
function TicketSheet({ ticket, open, onOpenChange }) {
|
|
2490
2534
|
const st = useSupportT();
|
|
2491
2535
|
const { user } = useAuth();
|
|
@@ -2494,6 +2538,7 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2494
2538
|
const [message, setMessage] = useState("");
|
|
2495
2539
|
const [isSending, setIsSending] = useState(false);
|
|
2496
2540
|
const scrollAreaRef = useRef(null);
|
|
2541
|
+
const textareaRef = useRef(null);
|
|
2497
2542
|
const firstRender = useRef(true);
|
|
2498
2543
|
const labels = useMemo(() => ({
|
|
2499
2544
|
noMessages: st("messageList.noMessages"),
|
|
@@ -2525,6 +2570,7 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2525
2570
|
refresh: refreshMessages,
|
|
2526
2571
|
addOptimistic
|
|
2527
2572
|
} = useMessages(ticket?.uuid || null);
|
|
2573
|
+
const messageGroups = useMemo(() => groupMessages(messages, user?.id), [messages, user?.id]);
|
|
2528
2574
|
useEffect(() => {
|
|
2529
2575
|
firstRender.current = true;
|
|
2530
2576
|
}, [ticket?.uuid]);
|
|
@@ -2537,6 +2583,14 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2537
2583
|
firstRender.current = false;
|
|
2538
2584
|
}
|
|
2539
2585
|
}, [messages]);
|
|
2586
|
+
const handleTextareaChange = useCallback((e) => {
|
|
2587
|
+
setMessage(e.target.value);
|
|
2588
|
+
const textarea = textareaRef.current;
|
|
2589
|
+
if (textarea) {
|
|
2590
|
+
textarea.style.height = "auto";
|
|
2591
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
|
|
2592
|
+
}
|
|
2593
|
+
}, []);
|
|
2540
2594
|
const handleSend = async (e) => {
|
|
2541
2595
|
e.preventDefault();
|
|
2542
2596
|
if (!message.trim() || !ticket?.uuid) return;
|
|
@@ -2562,6 +2616,9 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2562
2616
|
addOptimistic(optimisticMessage);
|
|
2563
2617
|
await sendMessage({ ticketUuid: ticket.uuid, text: messageText });
|
|
2564
2618
|
setMessage("");
|
|
2619
|
+
if (textareaRef.current) {
|
|
2620
|
+
textareaRef.current.style.height = "auto";
|
|
2621
|
+
}
|
|
2565
2622
|
await refreshMessages();
|
|
2566
2623
|
const scrollContainer = scrollAreaRef.current?.querySelector("[data-radix-scroll-area-viewport]");
|
|
2567
2624
|
if (scrollContainer) {
|
|
@@ -2595,32 +2652,61 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2595
2652
|
}, [loadMore]);
|
|
2596
2653
|
const canSendMessage = ticket?.status !== "closed";
|
|
2597
2654
|
const statusLabel = ticket ? labels.status[ticket.status] || ticket.status || labels.status.open : "";
|
|
2655
|
+
const statusConfig = getStatusConfig(ticket?.status || "open");
|
|
2656
|
+
const renderMessages = () => {
|
|
2657
|
+
const elements = [];
|
|
2658
|
+
let lastDate = null;
|
|
2659
|
+
for (const group of messageGroups) {
|
|
2660
|
+
const firstMessage = group.messages[0];
|
|
2661
|
+
if (!firstMessage) continue;
|
|
2662
|
+
const messageDate = firstMessage.created_at;
|
|
2663
|
+
if (!lastDate || !isSameDay(lastDate, messageDate)) {
|
|
2664
|
+
elements.push(
|
|
2665
|
+
/* @__PURE__ */ jsx(DateSeparator, { date: messageDate || "" }, `date-${messageDate}`)
|
|
2666
|
+
);
|
|
2667
|
+
lastDate = messageDate || null;
|
|
2668
|
+
}
|
|
2669
|
+
elements.push(
|
|
2670
|
+
/* @__PURE__ */ jsx(
|
|
2671
|
+
MessageGroupComponent,
|
|
2672
|
+
{
|
|
2673
|
+
group,
|
|
2674
|
+
currentUser: user,
|
|
2675
|
+
labels: { supportTeam: labels.supportTeam, staff: labels.staff }
|
|
2676
|
+
},
|
|
2677
|
+
`group-${firstMessage.uuid}`
|
|
2678
|
+
)
|
|
2679
|
+
);
|
|
2680
|
+
}
|
|
2681
|
+
return elements;
|
|
2682
|
+
};
|
|
2598
2683
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-xl p-0 flex flex-col h-full", children: [
|
|
2599
2684
|
/* @__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: [
|
|
2600
2685
|
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { className: "text-lg font-semibold line-clamp-2", children: ticket?.subject || "Ticket" }),
|
|
2601
2686
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
2602
|
-
/* @__PURE__ */ jsx(
|
|
2603
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
2687
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[13px] px-2 py-0.5 rounded-full", statusConfig.bg, statusConfig.color), children: statusLabel }),
|
|
2688
|
+
/* @__PURE__ */ jsx("span", { className: "text-[13px] text-muted-foreground", children: formatTicketDate(ticket?.created_at) })
|
|
2604
2689
|
] })
|
|
2605
2690
|
] }) }) }),
|
|
2606
|
-
/* @__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-
|
|
2607
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full" }),
|
|
2608
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-16
|
|
2691
|
+
/* @__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: [
|
|
2692
|
+
i % 2 !== 0 && /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" }),
|
|
2693
|
+
/* @__PURE__ */ jsx(Skeleton, { className: cn("h-16 rounded-[20px]", i % 2 === 0 ? "w-[60%]" : "w-[70%]") }),
|
|
2694
|
+
i % 2 === 0 && /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-8 rounded-full shrink-0" })
|
|
2609
2695
|
] }, i)) }) : messages.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center h-full p-8 text-center", children: [
|
|
2610
|
-
/* @__PURE__ */ jsx(MessageSquare, { className: "h-
|
|
2696
|
+
/* @__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" }) }),
|
|
2611
2697
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: labels.noMessages }),
|
|
2612
2698
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground max-w-sm", children: labels.noMessagesDescription })
|
|
2613
|
-
] }) : /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxs("div", { className: "p-
|
|
2699
|
+
] }) : /* @__PURE__ */ jsx(ScrollArea, { className: "h-full", viewportRef: scrollAreaRef, children: /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-3", children: [
|
|
2614
2700
|
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: [
|
|
2615
2701
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
2616
2702
|
/* @__PURE__ */ jsx("span", { className: "text-sm", children: labels.loadingOlder })
|
|
2617
2703
|
] }) : /* @__PURE__ */ jsxs(
|
|
2618
2704
|
Button,
|
|
2619
2705
|
{
|
|
2620
|
-
variant: "
|
|
2706
|
+
variant: "ghost",
|
|
2621
2707
|
size: "sm",
|
|
2622
2708
|
onClick: handleLoadMore,
|
|
2623
|
-
className: "text-xs",
|
|
2709
|
+
className: "text-xs text-muted-foreground",
|
|
2624
2710
|
children: [
|
|
2625
2711
|
labels.loadOlder,
|
|
2626
2712
|
" (",
|
|
@@ -2629,59 +2715,44 @@ function TicketSheet({ ticket, open, onOpenChange }) {
|
|
|
2629
2715
|
]
|
|
2630
2716
|
}
|
|
2631
2717
|
) }),
|
|
2632
|
-
|
|
2633
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2634
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(messages[0]?.created_at) }),
|
|
2635
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2636
|
-
] }),
|
|
2637
|
-
messages.map((msg, index) => {
|
|
2638
|
-
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);
|
|
2639
|
-
const previousMessage = index > 0 ? messages[index - 1] : null;
|
|
2640
|
-
const showDateSeparator = previousMessage && moment2.utc(previousMessage.created_at || "").format("YYYY-MM-DD") !== moment2.utc(msg.created_at || "").format("YYYY-MM-DD");
|
|
2641
|
-
return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
2642
|
-
showDateSeparator && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 my-4", children: [
|
|
2643
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" }),
|
|
2644
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDate(msg.created_at) }),
|
|
2645
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" })
|
|
2646
|
-
] }),
|
|
2647
|
-
/* @__PURE__ */ jsx(
|
|
2648
|
-
MessageBubble,
|
|
2649
|
-
{
|
|
2650
|
-
message: msg,
|
|
2651
|
-
isFromUser: !!isFromUser,
|
|
2652
|
-
currentUser: user,
|
|
2653
|
-
labels: { supportTeam: labels.supportTeam, staff: labels.staff }
|
|
2654
|
-
}
|
|
2655
|
-
)
|
|
2656
|
-
] }, msg.uuid);
|
|
2657
|
-
})
|
|
2718
|
+
renderMessages()
|
|
2658
2719
|
] }) }) }),
|
|
2659
|
-
/* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2720
|
+
/* @__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: [
|
|
2721
|
+
/* @__PURE__ */ jsx(
|
|
2722
|
+
"textarea",
|
|
2723
|
+
{
|
|
2724
|
+
ref: textareaRef,
|
|
2725
|
+
value: message,
|
|
2726
|
+
onChange: handleTextareaChange,
|
|
2727
|
+
onKeyDown: handleKeyDown,
|
|
2728
|
+
placeholder: labels.placeholder,
|
|
2729
|
+
className: cn(
|
|
2730
|
+
"flex-1 bg-transparent border-none resize-none",
|
|
2731
|
+
"text-[15px] placeholder:text-muted-foreground",
|
|
2732
|
+
"min-h-[24px] max-h-[120px] focus:outline-none"
|
|
2733
|
+
),
|
|
2734
|
+
rows: 1,
|
|
2735
|
+
disabled: isSending
|
|
2736
|
+
}
|
|
2737
|
+
),
|
|
2738
|
+
/* @__PURE__ */ jsx(
|
|
2739
|
+
Button,
|
|
2740
|
+
{
|
|
2741
|
+
type: "submit",
|
|
2742
|
+
size: "icon",
|
|
2743
|
+
variant: "ghost",
|
|
2744
|
+
className: cn(
|
|
2745
|
+
"rounded-full h-8 w-8 shrink-0",
|
|
2746
|
+
message.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : ""
|
|
2747
|
+
),
|
|
2748
|
+
disabled: !message.trim() || isSending,
|
|
2749
|
+
children: isSending ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4" })
|
|
2750
|
+
}
|
|
2751
|
+
)
|
|
2752
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "text-center py-2", children: [
|
|
2753
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: labels.ticketClosed }),
|
|
2754
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: labels.ticketClosedDescription })
|
|
2755
|
+
] }) })
|
|
2685
2756
|
] }) });
|
|
2686
2757
|
}
|
|
2687
2758
|
function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
@@ -2742,13 +2813,10 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2742
2813
|
};
|
|
2743
2814
|
return /* @__PURE__ */ jsx(ResponsiveSheet, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(ResponsiveSheetContent, { className: "sm:max-w-lg", children: [
|
|
2744
2815
|
/* @__PURE__ */ jsxs(ResponsiveSheetHeader, { children: [
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-5 w-5" }),
|
|
2747
|
-
labels.title
|
|
2748
|
-
] }),
|
|
2816
|
+
/* @__PURE__ */ jsx(ResponsiveSheetTitle, { children: labels.title }),
|
|
2749
2817
|
/* @__PURE__ */ jsx(ResponsiveSheetDescription, { children: labels.description })
|
|
2750
2818
|
] }),
|
|
2751
|
-
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-
|
|
2819
|
+
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: form.handleSubmit(onSubmit), className: "space-y-5 mt-4", children: [
|
|
2752
2820
|
/* @__PURE__ */ jsx(
|
|
2753
2821
|
FormField,
|
|
2754
2822
|
{
|
|
@@ -2788,7 +2856,7 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2788
2856
|
] })
|
|
2789
2857
|
}
|
|
2790
2858
|
),
|
|
2791
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-
|
|
2859
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-2", children: [
|
|
2792
2860
|
/* @__PURE__ */ jsx(
|
|
2793
2861
|
Button,
|
|
2794
2862
|
{
|
|
@@ -2802,10 +2870,7 @@ function CreateTicketSheet({ open, onOpenChange, onSuccess }) {
|
|
|
2802
2870
|
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2803
2871
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
2804
2872
|
labels.creating
|
|
2805
|
-
] }) :
|
|
2806
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-2" }),
|
|
2807
|
-
labels.create
|
|
2808
|
-
] }) })
|
|
2873
|
+
] }) : labels.create })
|
|
2809
2874
|
] })
|
|
2810
2875
|
] }) })
|
|
2811
2876
|
] }) });
|
|
@@ -2876,7 +2941,7 @@ function SupportPage({ isDemo = false }) {
|
|
|
2876
2941
|
// package.json
|
|
2877
2942
|
var package_default = {
|
|
2878
2943
|
name: "@djangocfg/ext-support",
|
|
2879
|
-
version: "1.0.
|
|
2944
|
+
version: "1.0.26",
|
|
2880
2945
|
description: "Support ticket system extension for DjangoCFG",
|
|
2881
2946
|
keywords: [
|
|
2882
2947
|
"django",
|