@consilioweb/payload-support 0.14.0 → 0.16.0
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/components/TicketConversation/components/ActionPanels.cjs +72 -0
- package/dist/components/TicketConversation/components/ActionPanels.js +73 -2
- package/dist/components/TicketConversation/components/QuickActions.cjs +22 -1
- package/dist/components/TicketConversation/components/QuickActions.js +22 -1
- package/dist/components/TicketConversation/hooks/useTicketActions.cjs +59 -0
- package/dist/components/TicketConversation/hooks/useTicketActions.js +59 -0
- package/dist/components/TicketConversation/index.cjs +32 -2
- package/dist/components/TicketConversation/index.js +33 -3
- package/dist/index.cjs +213 -52
- package/dist/index.js +213 -52
- package/dist/styles/Layout.module.scss +8 -11
- package/dist/styles/TicketDetail.module.scss +7 -8
- package/package.json +1 -1
- package/src/collections/TicketMessages.ts +8 -0
- package/src/collections/Tickets.ts +1 -0
- package/src/components/TicketConversation/components/ActionPanels.tsx +82 -1
- package/src/components/TicketConversation/components/QuickActions.tsx +25 -0
- package/src/components/TicketConversation/hooks/useTicketActions.ts +51 -0
- package/src/components/TicketConversation/index.tsx +25 -5
- package/src/endpoints/auto-close.ts +31 -7
- package/src/endpoints/index.ts +6 -1
- package/src/endpoints/send-reminder.ts +189 -0
- package/src/styles/Layout.module.scss +8 -11
- package/src/styles/TicketDetail.module.scss +7 -8
|
@@ -95,6 +95,77 @@ function ExtMessagePanel({
|
|
|
95
95
|
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleSendExtMsg, disabled: sendingExtMsg || !extMsgBody.trim(), style: constants.s.btn("#818cf8", sendingExtMsg || !extMsgBody.trim()), children: sendingExtMsg ? "Ajout..." : "Ajouter (sans notification)" })
|
|
96
96
|
] });
|
|
97
97
|
}
|
|
98
|
+
const REMINDER_DELAYS = [
|
|
99
|
+
{ hours: 24, label: "24 h" },
|
|
100
|
+
{ hours: 48, label: "48 h" },
|
|
101
|
+
{ hours: 72, label: "72 h" }
|
|
102
|
+
];
|
|
103
|
+
function ReminderPanel({
|
|
104
|
+
clientFirstName,
|
|
105
|
+
clientEmail,
|
|
106
|
+
reminderHours,
|
|
107
|
+
setReminderHours,
|
|
108
|
+
reminderSending,
|
|
109
|
+
reminderError,
|
|
110
|
+
handleSendReminder
|
|
111
|
+
}) {
|
|
112
|
+
const deadline = new Date(Date.now() + reminderHours * 60 * 60 * 1e3);
|
|
113
|
+
const deadlineLabel = deadline.toLocaleString("fr-FR", {
|
|
114
|
+
weekday: "long",
|
|
115
|
+
day: "numeric",
|
|
116
|
+
month: "long",
|
|
117
|
+
hour: "2-digit",
|
|
118
|
+
minute: "2-digit"
|
|
119
|
+
});
|
|
120
|
+
const name = clientFirstName?.trim() || "le client";
|
|
121
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#fff7ed", border: "1px solid #fed7aa", marginBottom: "14px" }, children: [
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px", color: "#9a3412" }, children: [
|
|
123
|
+
"Relancer ",
|
|
124
|
+
name,
|
|
125
|
+
" \u2014 fermeture automatique sans r\xE9ponse"
|
|
126
|
+
] }),
|
|
127
|
+
clientEmail ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "12px", color: "#7c2d12", margin: "0 0 12px 0", lineHeight: 1.5 }, children: [
|
|
128
|
+
"Un email de relance g\xE9n\xE9rique sera envoy\xE9 \xE0 ",
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: clientEmail }),
|
|
130
|
+
". Sans retour de sa part avant l'\xE9ch\xE9ance, le ticket sera automatiquement r\xE9solu (via le cron auto-close)."
|
|
131
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "12px", color: "#b91c1c", margin: "0 0 12px 0", fontWeight: 600 }, children: "Ce client n'a pas d'adresse email : impossible d'envoyer une relance." }),
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px", alignItems: "center", flexWrap: "wrap", marginBottom: "12px" }, children: [
|
|
133
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", fontWeight: 600, color: "#9a3412" }, children: "Fermer dans :" }),
|
|
134
|
+
REMINDER_DELAYS.map((d) => {
|
|
135
|
+
const active = reminderHours === d.hours;
|
|
136
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
+
"button",
|
|
138
|
+
{
|
|
139
|
+
type: "button",
|
|
140
|
+
onClick: () => setReminderHours(d.hours),
|
|
141
|
+
style: {
|
|
142
|
+
...active ? constants.s.btn(constants.C.orange) : constants.s.outlineBtn("#ea580c"),
|
|
143
|
+
fontSize: "12px",
|
|
144
|
+
padding: "6px 14px"
|
|
145
|
+
},
|
|
146
|
+
children: d.label
|
|
147
|
+
},
|
|
148
|
+
d.hours
|
|
149
|
+
);
|
|
150
|
+
})
|
|
151
|
+
] }),
|
|
152
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: "12px", color: "#7c2d12", marginBottom: "12px" }, children: [
|
|
153
|
+
"Fermeture automatique pr\xE9vue le ",
|
|
154
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: deadlineLabel }),
|
|
155
|
+
" sans r\xE9ponse."
|
|
156
|
+
] }),
|
|
157
|
+
reminderError && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "12px", color: "#b91c1c", fontWeight: 600, marginBottom: "10px" }, children: reminderError }),
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
"button",
|
|
160
|
+
{
|
|
161
|
+
onClick: handleSendReminder,
|
|
162
|
+
disabled: reminderSending || !clientEmail,
|
|
163
|
+
style: { ...constants.s.btn(constants.C.orange, reminderSending || !clientEmail), color: "#fff", fontSize: "13px", padding: "8px 18px" },
|
|
164
|
+
children: reminderSending ? "Envoi..." : "Confirmer la relance"
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
] });
|
|
168
|
+
}
|
|
98
169
|
function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
99
170
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#faf5ff", border: "1px solid #e9d5ff", marginBottom: "14px" }, children: [
|
|
100
171
|
/* @__PURE__ */ jsxRuntime.jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#5b21b6" }, children: "Snooze \u2014 masquer temporairement" }),
|
|
@@ -118,4 +189,5 @@ function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
|
118
189
|
|
|
119
190
|
exports.ExtMessagePanel = ExtMessagePanel;
|
|
120
191
|
exports.MergePanel = MergePanel;
|
|
192
|
+
exports.ReminderPanel = ReminderPanel;
|
|
121
193
|
exports.SnoozePanel = SnoozePanel;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useRef } from 'react';
|
|
4
|
-
import { s } from '../constants.js';
|
|
4
|
+
import { s, C } from '../constants.js';
|
|
5
5
|
|
|
6
6
|
function MergePanel({
|
|
7
7
|
mergeTarget,
|
|
@@ -94,6 +94,77 @@ function ExtMessagePanel({
|
|
|
94
94
|
/* @__PURE__ */ jsx("button", { onClick: handleSendExtMsg, disabled: sendingExtMsg || !extMsgBody.trim(), style: s.btn("#818cf8", sendingExtMsg || !extMsgBody.trim()), children: sendingExtMsg ? "Ajout..." : "Ajouter (sans notification)" })
|
|
95
95
|
] });
|
|
96
96
|
}
|
|
97
|
+
const REMINDER_DELAYS = [
|
|
98
|
+
{ hours: 24, label: "24 h" },
|
|
99
|
+
{ hours: 48, label: "48 h" },
|
|
100
|
+
{ hours: 72, label: "72 h" }
|
|
101
|
+
];
|
|
102
|
+
function ReminderPanel({
|
|
103
|
+
clientFirstName,
|
|
104
|
+
clientEmail,
|
|
105
|
+
reminderHours,
|
|
106
|
+
setReminderHours,
|
|
107
|
+
reminderSending,
|
|
108
|
+
reminderError,
|
|
109
|
+
handleSendReminder
|
|
110
|
+
}) {
|
|
111
|
+
const deadline = new Date(Date.now() + reminderHours * 60 * 60 * 1e3);
|
|
112
|
+
const deadlineLabel = deadline.toLocaleString("fr-FR", {
|
|
113
|
+
weekday: "long",
|
|
114
|
+
day: "numeric",
|
|
115
|
+
month: "long",
|
|
116
|
+
hour: "2-digit",
|
|
117
|
+
minute: "2-digit"
|
|
118
|
+
});
|
|
119
|
+
const name = clientFirstName?.trim() || "le client";
|
|
120
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#fff7ed", border: "1px solid #fed7aa", marginBottom: "14px" }, children: [
|
|
121
|
+
/* @__PURE__ */ jsxs("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px", color: "#9a3412" }, children: [
|
|
122
|
+
"Relancer ",
|
|
123
|
+
name,
|
|
124
|
+
" \u2014 fermeture automatique sans r\xE9ponse"
|
|
125
|
+
] }),
|
|
126
|
+
clientEmail ? /* @__PURE__ */ jsxs("p", { style: { fontSize: "12px", color: "#7c2d12", margin: "0 0 12px 0", lineHeight: 1.5 }, children: [
|
|
127
|
+
"Un email de relance g\xE9n\xE9rique sera envoy\xE9 \xE0 ",
|
|
128
|
+
/* @__PURE__ */ jsx("strong", { children: clientEmail }),
|
|
129
|
+
". Sans retour de sa part avant l'\xE9ch\xE9ance, le ticket sera automatiquement r\xE9solu (via le cron auto-close)."
|
|
130
|
+
] }) : /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "#b91c1c", margin: "0 0 12px 0", fontWeight: 600 }, children: "Ce client n'a pas d'adresse email : impossible d'envoyer une relance." }),
|
|
131
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px", alignItems: "center", flexWrap: "wrap", marginBottom: "12px" }, children: [
|
|
132
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "12px", fontWeight: 600, color: "#9a3412" }, children: "Fermer dans :" }),
|
|
133
|
+
REMINDER_DELAYS.map((d) => {
|
|
134
|
+
const active = reminderHours === d.hours;
|
|
135
|
+
return /* @__PURE__ */ jsx(
|
|
136
|
+
"button",
|
|
137
|
+
{
|
|
138
|
+
type: "button",
|
|
139
|
+
onClick: () => setReminderHours(d.hours),
|
|
140
|
+
style: {
|
|
141
|
+
...active ? s.btn(C.orange) : s.outlineBtn("#ea580c"),
|
|
142
|
+
fontSize: "12px",
|
|
143
|
+
padding: "6px 14px"
|
|
144
|
+
},
|
|
145
|
+
children: d.label
|
|
146
|
+
},
|
|
147
|
+
d.hours
|
|
148
|
+
);
|
|
149
|
+
})
|
|
150
|
+
] }),
|
|
151
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "12px", color: "#7c2d12", marginBottom: "12px" }, children: [
|
|
152
|
+
"Fermeture automatique pr\xE9vue le ",
|
|
153
|
+
/* @__PURE__ */ jsx("strong", { children: deadlineLabel }),
|
|
154
|
+
" sans r\xE9ponse."
|
|
155
|
+
] }),
|
|
156
|
+
reminderError && /* @__PURE__ */ jsx("div", { style: { fontSize: "12px", color: "#b91c1c", fontWeight: 600, marginBottom: "10px" }, children: reminderError }),
|
|
157
|
+
/* @__PURE__ */ jsx(
|
|
158
|
+
"button",
|
|
159
|
+
{
|
|
160
|
+
onClick: handleSendReminder,
|
|
161
|
+
disabled: reminderSending || !clientEmail,
|
|
162
|
+
style: { ...s.btn(C.orange, reminderSending || !clientEmail), color: "#fff", fontSize: "13px", padding: "8px 18px" },
|
|
163
|
+
children: reminderSending ? "Envoi..." : "Confirmer la relance"
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
] });
|
|
167
|
+
}
|
|
97
168
|
function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
98
169
|
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#faf5ff", border: "1px solid #e9d5ff", marginBottom: "14px" }, children: [
|
|
99
170
|
/* @__PURE__ */ jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#5b21b6" }, children: "Snooze \u2014 masquer temporairement" }),
|
|
@@ -115,4 +186,4 @@ function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
|
115
186
|
] });
|
|
116
187
|
}
|
|
117
188
|
|
|
118
|
-
export { ExtMessagePanel, MergePanel, SnoozePanel };
|
|
189
|
+
export { ExtMessagePanel, MergePanel, ReminderPanel, SnoozePanel };
|
|
@@ -17,11 +17,18 @@ function QuickActions({
|
|
|
17
17
|
onToggleExtMsg,
|
|
18
18
|
onToggleSnooze,
|
|
19
19
|
onNextTicket,
|
|
20
|
+
showReminderButton,
|
|
21
|
+
onToggleReminder,
|
|
22
|
+
autoCloseScheduledAt,
|
|
23
|
+
onCancelScheduledClose,
|
|
24
|
+
cancelingClose,
|
|
25
|
+
reminderSuccess,
|
|
20
26
|
showNextTicket,
|
|
21
27
|
nextTicketId,
|
|
22
28
|
nextTicketInfo,
|
|
23
29
|
onCloseNextTicket
|
|
24
30
|
}) {
|
|
31
|
+
const scheduledClose = autoCloseScheduledAt && new Date(autoCloseScheduledAt) > /* @__PURE__ */ new Date() ? new Date(autoCloseScheduledAt).toLocaleString("fr-FR", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }) : null;
|
|
25
32
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
26
33
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", marginBottom: "16px", alignItems: "center" }, children: [
|
|
27
34
|
statusTransitions.map((a) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -39,7 +46,21 @@ function QuickActions({
|
|
|
39
46
|
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onToggleMerge, style: constants.s.ghostBtn("#be185d"), children: "Fusionner" }),
|
|
40
47
|
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onToggleExtMsg, style: constants.s.ghostBtn("#4f46e5"), children: "+ Message re\xE7u" }),
|
|
41
48
|
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onToggleSnooze, style: constants.s.ghostBtn("#7c3aed"), children: "Snooze" }),
|
|
42
|
-
/* @__PURE__ */ jsxRuntime.
|
|
49
|
+
showReminderButton && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: onToggleReminder, style: constants.s.ghostBtn("#ea580c"), children: [
|
|
50
|
+
"\u23F0",
|
|
51
|
+
" Relancer"
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onNextTicket, style: constants.s.ghostBtn("#16a34a"), children: "Ticket suivant" }),
|
|
54
|
+
scheduledClose && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "8px", padding: "5px 10px", borderRadius: "6px", backgroundColor: "#fff7ed", border: "1px solid #fed7aa", fontSize: "12px", color: "#9a3412", fontWeight: 600 }, children: [
|
|
55
|
+
"\u23F0",
|
|
56
|
+
" Fermeture auto le ",
|
|
57
|
+
scheduledClose,
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onCancelScheduledClose, disabled: cancelingClose, style: { border: "none", background: "none", color: "#b91c1c", cursor: cancelingClose ? "not-allowed" : "pointer", fontWeight: 700, fontSize: "12px", textDecoration: "underline", padding: 0, opacity: cancelingClose ? 0.5 : 1 }, children: cancelingClose ? "..." : "Annuler" })
|
|
59
|
+
] }),
|
|
60
|
+
reminderSuccess && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { ...constants.s.badge("#f0fdf4", "#16a34a"), fontSize: "12px", padding: "5px 10px" }, children: [
|
|
61
|
+
"Relance envoy\xE9e ",
|
|
62
|
+
"\u2713"
|
|
63
|
+
] })
|
|
43
64
|
] }),
|
|
44
65
|
showNextTicket && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "10px 14px", borderRadius: "8px", backgroundColor: "#f0fdf4", border: `1px solid ${constants.C.border}`, marginBottom: "14px", display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
45
66
|
nextTicketId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -16,11 +16,18 @@ function QuickActions({
|
|
|
16
16
|
onToggleExtMsg,
|
|
17
17
|
onToggleSnooze,
|
|
18
18
|
onNextTicket,
|
|
19
|
+
showReminderButton,
|
|
20
|
+
onToggleReminder,
|
|
21
|
+
autoCloseScheduledAt,
|
|
22
|
+
onCancelScheduledClose,
|
|
23
|
+
cancelingClose,
|
|
24
|
+
reminderSuccess,
|
|
19
25
|
showNextTicket,
|
|
20
26
|
nextTicketId,
|
|
21
27
|
nextTicketInfo,
|
|
22
28
|
onCloseNextTicket
|
|
23
29
|
}) {
|
|
30
|
+
const scheduledClose = autoCloseScheduledAt && new Date(autoCloseScheduledAt) > /* @__PURE__ */ new Date() ? new Date(autoCloseScheduledAt).toLocaleString("fr-FR", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }) : null;
|
|
24
31
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
32
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", marginBottom: "16px", alignItems: "center" }, children: [
|
|
26
33
|
statusTransitions.map((a) => /* @__PURE__ */ jsx(
|
|
@@ -38,7 +45,21 @@ function QuickActions({
|
|
|
38
45
|
/* @__PURE__ */ jsx("button", { onClick: onToggleMerge, style: s.ghostBtn("#be185d"), children: "Fusionner" }),
|
|
39
46
|
/* @__PURE__ */ jsx("button", { onClick: onToggleExtMsg, style: s.ghostBtn("#4f46e5"), children: "+ Message re\xE7u" }),
|
|
40
47
|
/* @__PURE__ */ jsx("button", { onClick: onToggleSnooze, style: s.ghostBtn("#7c3aed"), children: "Snooze" }),
|
|
41
|
-
/* @__PURE__ */
|
|
48
|
+
showReminderButton && /* @__PURE__ */ jsxs("button", { onClick: onToggleReminder, style: s.ghostBtn("#ea580c"), children: [
|
|
49
|
+
"\u23F0",
|
|
50
|
+
" Relancer"
|
|
51
|
+
] }),
|
|
52
|
+
/* @__PURE__ */ jsx("button", { onClick: onNextTicket, style: s.ghostBtn("#16a34a"), children: "Ticket suivant" }),
|
|
53
|
+
scheduledClose && /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "8px", padding: "5px 10px", borderRadius: "6px", backgroundColor: "#fff7ed", border: "1px solid #fed7aa", fontSize: "12px", color: "#9a3412", fontWeight: 600 }, children: [
|
|
54
|
+
"\u23F0",
|
|
55
|
+
" Fermeture auto le ",
|
|
56
|
+
scheduledClose,
|
|
57
|
+
/* @__PURE__ */ jsx("button", { onClick: onCancelScheduledClose, disabled: cancelingClose, style: { border: "none", background: "none", color: "#b91c1c", cursor: cancelingClose ? "not-allowed" : "pointer", fontWeight: 700, fontSize: "12px", textDecoration: "underline", padding: 0, opacity: cancelingClose ? 0.5 : 1 }, children: cancelingClose ? "..." : "Annuler" })
|
|
58
|
+
] }),
|
|
59
|
+
reminderSuccess && /* @__PURE__ */ jsxs("span", { style: { ...s.badge("#f0fdf4", "#16a34a"), fontSize: "12px", padding: "5px 10px" }, children: [
|
|
60
|
+
"Relance envoy\xE9e ",
|
|
61
|
+
"\u2713"
|
|
62
|
+
] })
|
|
42
63
|
] }),
|
|
43
64
|
showNextTicket && /* @__PURE__ */ jsxs("div", { style: { padding: "10px 14px", borderRadius: "8px", backgroundColor: "#f0fdf4", border: `1px solid ${C.border}`, marginBottom: "14px", display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
44
65
|
nextTicketId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -19,6 +19,12 @@ function useTicketActions(id, fetchAll) {
|
|
|
19
19
|
const [showSnooze, setShowSnooze] = react.useState(false);
|
|
20
20
|
const [snoozeUntil, setSnoozeUntil] = react.useState(null);
|
|
21
21
|
const [snoozeSaving, setSnoozeSaving] = react.useState(false);
|
|
22
|
+
const [showReminder, setShowReminder] = react.useState(false);
|
|
23
|
+
const [reminderHours, setReminderHours] = react.useState(24);
|
|
24
|
+
const [reminderSending, setReminderSending] = react.useState(false);
|
|
25
|
+
const [reminderError, setReminderError] = react.useState("");
|
|
26
|
+
const [reminderSuccess, setReminderSuccess] = react.useState(false);
|
|
27
|
+
const [cancelingClose, setCancelingClose] = react.useState(false);
|
|
22
28
|
const [showNextTicket, setShowNextTicket] = react.useState(false);
|
|
23
29
|
const [nextTicketId, setNextTicketId] = react.useState(null);
|
|
24
30
|
const [nextTicketInfo, setNextTicketInfo] = react.useState("");
|
|
@@ -170,6 +176,48 @@ function useTicketActions(id, fetchAll) {
|
|
|
170
176
|
setSnoozeSaving(false);
|
|
171
177
|
}
|
|
172
178
|
};
|
|
179
|
+
const handleSendReminder = async () => {
|
|
180
|
+
if (!id) return;
|
|
181
|
+
setReminderSending(true);
|
|
182
|
+
setReminderError("");
|
|
183
|
+
try {
|
|
184
|
+
const res = await fetch("/api/support/send-reminder", {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: { "Content-Type": "application/json" },
|
|
187
|
+
credentials: "include",
|
|
188
|
+
body: JSON.stringify({ ticketId: id, hours: reminderHours })
|
|
189
|
+
});
|
|
190
|
+
const d = await res.json().catch(() => ({}));
|
|
191
|
+
if (res.ok) {
|
|
192
|
+
setShowReminder(false);
|
|
193
|
+
setReminderSuccess(true);
|
|
194
|
+
setTimeout(() => setReminderSuccess(false), 5e3);
|
|
195
|
+
fetchAll();
|
|
196
|
+
} else {
|
|
197
|
+
setReminderError(d.error || "Erreur lors de la relance");
|
|
198
|
+
}
|
|
199
|
+
} catch {
|
|
200
|
+
setReminderError("Erreur r\xE9seau");
|
|
201
|
+
} finally {
|
|
202
|
+
setReminderSending(false);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const handleCancelScheduledClose = async () => {
|
|
206
|
+
if (!id) return;
|
|
207
|
+
setCancelingClose(true);
|
|
208
|
+
try {
|
|
209
|
+
await fetch(`/api/tickets/${id}`, {
|
|
210
|
+
method: "PATCH",
|
|
211
|
+
headers: { "Content-Type": "application/json" },
|
|
212
|
+
credentials: "include",
|
|
213
|
+
body: JSON.stringify({ autoCloseScheduledAt: null, autoCloseRemindedAt: null })
|
|
214
|
+
});
|
|
215
|
+
fetchAll();
|
|
216
|
+
} catch {
|
|
217
|
+
} finally {
|
|
218
|
+
setCancelingClose(false);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
173
221
|
const handleNextTicket = async () => {
|
|
174
222
|
try {
|
|
175
223
|
const res = await fetch("/api/tickets?where[status][equals]=open&sort=updatedAt&limit=1&depth=0", { credentials: "include" });
|
|
@@ -220,6 +268,17 @@ function useTicketActions(id, fetchAll) {
|
|
|
220
268
|
setSnoozeUntil,
|
|
221
269
|
snoozeSaving,
|
|
222
270
|
handleSnooze,
|
|
271
|
+
showReminder,
|
|
272
|
+
setShowReminder,
|
|
273
|
+
reminderHours,
|
|
274
|
+
setReminderHours,
|
|
275
|
+
reminderSending,
|
|
276
|
+
reminderError,
|
|
277
|
+
setReminderError,
|
|
278
|
+
reminderSuccess,
|
|
279
|
+
handleSendReminder,
|
|
280
|
+
cancelingClose,
|
|
281
|
+
handleCancelScheduledClose,
|
|
223
282
|
showNextTicket,
|
|
224
283
|
setShowNextTicket,
|
|
225
284
|
nextTicketId,
|
|
@@ -18,6 +18,12 @@ function useTicketActions(id, fetchAll) {
|
|
|
18
18
|
const [showSnooze, setShowSnooze] = useState(false);
|
|
19
19
|
const [snoozeUntil, setSnoozeUntil] = useState(null);
|
|
20
20
|
const [snoozeSaving, setSnoozeSaving] = useState(false);
|
|
21
|
+
const [showReminder, setShowReminder] = useState(false);
|
|
22
|
+
const [reminderHours, setReminderHours] = useState(24);
|
|
23
|
+
const [reminderSending, setReminderSending] = useState(false);
|
|
24
|
+
const [reminderError, setReminderError] = useState("");
|
|
25
|
+
const [reminderSuccess, setReminderSuccess] = useState(false);
|
|
26
|
+
const [cancelingClose, setCancelingClose] = useState(false);
|
|
21
27
|
const [showNextTicket, setShowNextTicket] = useState(false);
|
|
22
28
|
const [nextTicketId, setNextTicketId] = useState(null);
|
|
23
29
|
const [nextTicketInfo, setNextTicketInfo] = useState("");
|
|
@@ -169,6 +175,48 @@ function useTicketActions(id, fetchAll) {
|
|
|
169
175
|
setSnoozeSaving(false);
|
|
170
176
|
}
|
|
171
177
|
};
|
|
178
|
+
const handleSendReminder = async () => {
|
|
179
|
+
if (!id) return;
|
|
180
|
+
setReminderSending(true);
|
|
181
|
+
setReminderError("");
|
|
182
|
+
try {
|
|
183
|
+
const res = await fetch("/api/support/send-reminder", {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: { "Content-Type": "application/json" },
|
|
186
|
+
credentials: "include",
|
|
187
|
+
body: JSON.stringify({ ticketId: id, hours: reminderHours })
|
|
188
|
+
});
|
|
189
|
+
const d = await res.json().catch(() => ({}));
|
|
190
|
+
if (res.ok) {
|
|
191
|
+
setShowReminder(false);
|
|
192
|
+
setReminderSuccess(true);
|
|
193
|
+
setTimeout(() => setReminderSuccess(false), 5e3);
|
|
194
|
+
fetchAll();
|
|
195
|
+
} else {
|
|
196
|
+
setReminderError(d.error || "Erreur lors de la relance");
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
setReminderError("Erreur r\xE9seau");
|
|
200
|
+
} finally {
|
|
201
|
+
setReminderSending(false);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const handleCancelScheduledClose = async () => {
|
|
205
|
+
if (!id) return;
|
|
206
|
+
setCancelingClose(true);
|
|
207
|
+
try {
|
|
208
|
+
await fetch(`/api/tickets/${id}`, {
|
|
209
|
+
method: "PATCH",
|
|
210
|
+
headers: { "Content-Type": "application/json" },
|
|
211
|
+
credentials: "include",
|
|
212
|
+
body: JSON.stringify({ autoCloseScheduledAt: null, autoCloseRemindedAt: null })
|
|
213
|
+
});
|
|
214
|
+
fetchAll();
|
|
215
|
+
} catch {
|
|
216
|
+
} finally {
|
|
217
|
+
setCancelingClose(false);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
172
220
|
const handleNextTicket = async () => {
|
|
173
221
|
try {
|
|
174
222
|
const res = await fetch("/api/tickets?where[status][equals]=open&sort=updatedAt&limit=1&depth=0", { credentials: "include" });
|
|
@@ -219,6 +267,17 @@ function useTicketActions(id, fetchAll) {
|
|
|
219
267
|
setSnoozeUntil,
|
|
220
268
|
snoozeSaving,
|
|
221
269
|
handleSnooze,
|
|
270
|
+
showReminder,
|
|
271
|
+
setShowReminder,
|
|
272
|
+
reminderHours,
|
|
273
|
+
setReminderHours,
|
|
274
|
+
reminderSending,
|
|
275
|
+
reminderError,
|
|
276
|
+
setReminderError,
|
|
277
|
+
reminderSuccess,
|
|
278
|
+
handleSendReminder,
|
|
279
|
+
cancelingClose,
|
|
280
|
+
handleCancelScheduledClose,
|
|
222
281
|
showNextTicket,
|
|
223
282
|
setShowNextTicket,
|
|
224
283
|
nextTicketId,
|
|
@@ -188,6 +188,7 @@ const TicketConversation = () => {
|
|
|
188
188
|
const [ticketSubject, setTicketSubject] = React.useState("");
|
|
189
189
|
const [ticketSource, setTicketSource] = React.useState("");
|
|
190
190
|
const [chatSession, setChatSession] = React.useState("");
|
|
191
|
+
const [autoCloseScheduledAt, setAutoCloseScheduledAt] = React.useState(null);
|
|
191
192
|
const [clientTickets, setClientTickets] = React.useState([]);
|
|
192
193
|
const [clientProjects, setClientProjects] = React.useState([]);
|
|
193
194
|
const [clientNotes, setClientNotes] = React.useState("");
|
|
@@ -220,6 +221,7 @@ const TicketConversation = () => {
|
|
|
220
221
|
setClient(d.client);
|
|
221
222
|
}
|
|
222
223
|
setSnoozeUntil(d.snoozeUntil || null);
|
|
224
|
+
setAutoCloseScheduledAt(d.autoCloseScheduledAt || null);
|
|
223
225
|
setLastClientReadAt(d.lastClientReadAt || null);
|
|
224
226
|
setCurrentStatus(d.status || "");
|
|
225
227
|
setTicketNumber(d.ticketNumber || "");
|
|
@@ -364,7 +366,7 @@ const TicketConversation = () => {
|
|
|
364
366
|
const ma = useMessageActions.useMessageActions(id, client, fetchAll);
|
|
365
367
|
const { togglingAuthor, editingMsg, editBody, editHtml, setEditHtml, savingEdit, handleEditStart, handleEditSave, handleEditCancel, deletingMsg, handleDelete, resendingMsg, resendSuccess, handleResend, handleToggleAuthor, handleSplitMessage, setEditBody } = ma;
|
|
366
368
|
const ta = useTicketActions.useTicketActions(id, fetchAll);
|
|
367
|
-
const { statusUpdating, handleStatusChange, showMerge, setShowMerge, mergeTarget, setMergeTarget, mergeTargetInfo, setMergeTargetInfo, mergeError, setMergeError, merging, handleMergeLookup, handleMerge, showExtMsg, setShowExtMsg, extMsgBody, setExtMsgBody, extMsgAuthor, setExtMsgAuthor, extMsgDate, setExtMsgDate, extMsgFiles, setExtMsgFiles, sendingExtMsg, handleExtFileChange, handleSendExtMsg, showSnooze, setShowSnooze, snoozeUntil, setSnoozeUntil, snoozeSaving, handleSnooze, showNextTicket, setShowNextTicket, nextTicketId, nextTicketInfo, handleNextTicket } = ta;
|
|
369
|
+
const { statusUpdating, handleStatusChange, showMerge, setShowMerge, mergeTarget, setMergeTarget, mergeTargetInfo, setMergeTargetInfo, mergeError, setMergeError, merging, handleMergeLookup, handleMerge, showExtMsg, setShowExtMsg, extMsgBody, setExtMsgBody, extMsgAuthor, setExtMsgAuthor, extMsgDate, setExtMsgDate, extMsgFiles, setExtMsgFiles, sendingExtMsg, handleExtFileChange, handleSendExtMsg, showSnooze, setShowSnooze, snoozeUntil, setSnoozeUntil, snoozeSaving, handleSnooze, showReminder, setShowReminder, reminderHours, setReminderHours, reminderSending, reminderError, setReminderError, reminderSuccess, handleSendReminder, cancelingClose, handleCancelScheduledClose, showNextTicket, setShowNextTicket, nextTicketId, nextTicketInfo, handleNextTicket } = ta;
|
|
368
370
|
const replyEditorRef = React.useRef(null);
|
|
369
371
|
const rp = useReply.useReply(id, client, cannedResponses, ticketNumber, ticketSubject, fetchAll, handleNextTicket, replyEditorRef);
|
|
370
372
|
const { fileInputRef, replyBody, setReplyBody, replyHtml, setReplyHtml, replyFiles, setReplyFiles, isInternal, setIsInternal, notifyClient, setNotifyClient, sendAsClient, setSendAsClient, sending, showSchedule, setShowSchedule, scheduleDate, setScheduleDate, handleEditorFileUpload, handleCannedSelect, handleReplyFileChange, handleSendReply, handleScheduleReply } = rp;
|
|
@@ -393,6 +395,7 @@ const TicketConversation = () => {
|
|
|
393
395
|
const d = await ticketRes.json();
|
|
394
396
|
setCurrentStatus(d.status || "");
|
|
395
397
|
setSnoozeUntil(d.snoozeUntil || null);
|
|
398
|
+
setAutoCloseScheduledAt(d.autoCloseScheduledAt || null);
|
|
396
399
|
setLastClientReadAt(d.lastClientReadAt || null);
|
|
397
400
|
}
|
|
398
401
|
if (activityRes.ok) {
|
|
@@ -1080,18 +1083,33 @@ const TicketConversation = () => {
|
|
|
1080
1083
|
setShowMerge(!showMerge);
|
|
1081
1084
|
setShowExtMsg(false);
|
|
1082
1085
|
setShowSnooze(false);
|
|
1086
|
+
setShowReminder(false);
|
|
1083
1087
|
},
|
|
1084
1088
|
onToggleExtMsg: () => {
|
|
1085
1089
|
setShowExtMsg(!showExtMsg);
|
|
1086
1090
|
setShowMerge(false);
|
|
1087
1091
|
setShowSnooze(false);
|
|
1092
|
+
setShowReminder(false);
|
|
1088
1093
|
},
|
|
1089
1094
|
onToggleSnooze: () => {
|
|
1090
1095
|
setShowSnooze(!showSnooze);
|
|
1091
1096
|
setShowMerge(false);
|
|
1092
1097
|
setShowExtMsg(false);
|
|
1098
|
+
setShowReminder(false);
|
|
1093
1099
|
},
|
|
1094
1100
|
onNextTicket: handleNextTicket,
|
|
1101
|
+
showReminderButton: features.autoClose,
|
|
1102
|
+
onToggleReminder: () => {
|
|
1103
|
+
setShowReminder(!showReminder);
|
|
1104
|
+
setReminderError("");
|
|
1105
|
+
setShowMerge(false);
|
|
1106
|
+
setShowExtMsg(false);
|
|
1107
|
+
setShowSnooze(false);
|
|
1108
|
+
},
|
|
1109
|
+
autoCloseScheduledAt,
|
|
1110
|
+
onCancelScheduledClose: handleCancelScheduledClose,
|
|
1111
|
+
cancelingClose,
|
|
1112
|
+
reminderSuccess,
|
|
1095
1113
|
showNextTicket,
|
|
1096
1114
|
nextTicketId,
|
|
1097
1115
|
nextTicketInfo,
|
|
@@ -1141,7 +1159,19 @@ const TicketConversation = () => {
|
|
|
1141
1159
|
handleExtFileChange
|
|
1142
1160
|
}
|
|
1143
1161
|
),
|
|
1144
|
-
features.snooze && showSnooze && /* @__PURE__ */ jsxRuntime.jsx(ActionPanels.SnoozePanel, { snoozeSaving, handleSnooze })
|
|
1162
|
+
features.snooze && showSnooze && /* @__PURE__ */ jsxRuntime.jsx(ActionPanels.SnoozePanel, { snoozeSaving, handleSnooze }),
|
|
1163
|
+
features.autoClose && showReminder && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1164
|
+
ActionPanels.ReminderPanel,
|
|
1165
|
+
{
|
|
1166
|
+
clientFirstName: client?.firstName || "",
|
|
1167
|
+
clientEmail: client?.email || "",
|
|
1168
|
+
reminderHours,
|
|
1169
|
+
setReminderHours,
|
|
1170
|
+
reminderSending,
|
|
1171
|
+
reminderError,
|
|
1172
|
+
handleSendReminder
|
|
1173
|
+
}
|
|
1174
|
+
)
|
|
1145
1175
|
] }),
|
|
1146
1176
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: layoutStyles.sideColumn, children: [
|
|
1147
1177
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9,7 +9,7 @@ import { TicketHeader } from './components/TicketHeader.js';
|
|
|
9
9
|
import { ClientBar } from './components/ClientBar.js';
|
|
10
10
|
import { QuickActions } from './components/QuickActions.js';
|
|
11
11
|
import { AISummaryPanel } from './components/AISummaryPanel.js';
|
|
12
|
-
import { MergePanel, ExtMessagePanel, SnoozePanel } from './components/ActionPanels.js';
|
|
12
|
+
import { MergePanel, ExtMessagePanel, SnoozePanel, ReminderPanel } from './components/ActionPanels.js';
|
|
13
13
|
import { ActivityLog } from './components/ActivityLog.js';
|
|
14
14
|
import { ClientHistory } from './components/ClientHistory.js';
|
|
15
15
|
import { TimeTrackingPanel } from './components/TimeTrackingPanel.js';
|
|
@@ -183,6 +183,7 @@ const TicketConversation = () => {
|
|
|
183
183
|
const [ticketSubject, setTicketSubject] = useState("");
|
|
184
184
|
const [ticketSource, setTicketSource] = useState("");
|
|
185
185
|
const [chatSession, setChatSession] = useState("");
|
|
186
|
+
const [autoCloseScheduledAt, setAutoCloseScheduledAt] = useState(null);
|
|
186
187
|
const [clientTickets, setClientTickets] = useState([]);
|
|
187
188
|
const [clientProjects, setClientProjects] = useState([]);
|
|
188
189
|
const [clientNotes, setClientNotes] = useState("");
|
|
@@ -215,6 +216,7 @@ const TicketConversation = () => {
|
|
|
215
216
|
setClient(d.client);
|
|
216
217
|
}
|
|
217
218
|
setSnoozeUntil(d.snoozeUntil || null);
|
|
219
|
+
setAutoCloseScheduledAt(d.autoCloseScheduledAt || null);
|
|
218
220
|
setLastClientReadAt(d.lastClientReadAt || null);
|
|
219
221
|
setCurrentStatus(d.status || "");
|
|
220
222
|
setTicketNumber(d.ticketNumber || "");
|
|
@@ -359,7 +361,7 @@ const TicketConversation = () => {
|
|
|
359
361
|
const ma = useMessageActions(id, client, fetchAll);
|
|
360
362
|
const { togglingAuthor, editingMsg, editBody, editHtml, setEditHtml, savingEdit, handleEditStart, handleEditSave, handleEditCancel, deletingMsg, handleDelete, resendingMsg, resendSuccess, handleResend, handleToggleAuthor, handleSplitMessage, setEditBody } = ma;
|
|
361
363
|
const ta = useTicketActions(id, fetchAll);
|
|
362
|
-
const { statusUpdating, handleStatusChange, showMerge, setShowMerge, mergeTarget, setMergeTarget, mergeTargetInfo, setMergeTargetInfo, mergeError, setMergeError, merging, handleMergeLookup, handleMerge, showExtMsg, setShowExtMsg, extMsgBody, setExtMsgBody, extMsgAuthor, setExtMsgAuthor, extMsgDate, setExtMsgDate, extMsgFiles, setExtMsgFiles, sendingExtMsg, handleExtFileChange, handleSendExtMsg, showSnooze, setShowSnooze, snoozeUntil, setSnoozeUntil, snoozeSaving, handleSnooze, showNextTicket, setShowNextTicket, nextTicketId, nextTicketInfo, handleNextTicket } = ta;
|
|
364
|
+
const { statusUpdating, handleStatusChange, showMerge, setShowMerge, mergeTarget, setMergeTarget, mergeTargetInfo, setMergeTargetInfo, mergeError, setMergeError, merging, handleMergeLookup, handleMerge, showExtMsg, setShowExtMsg, extMsgBody, setExtMsgBody, extMsgAuthor, setExtMsgAuthor, extMsgDate, setExtMsgDate, extMsgFiles, setExtMsgFiles, sendingExtMsg, handleExtFileChange, handleSendExtMsg, showSnooze, setShowSnooze, snoozeUntil, setSnoozeUntil, snoozeSaving, handleSnooze, showReminder, setShowReminder, reminderHours, setReminderHours, reminderSending, reminderError, setReminderError, reminderSuccess, handleSendReminder, cancelingClose, handleCancelScheduledClose, showNextTicket, setShowNextTicket, nextTicketId, nextTicketInfo, handleNextTicket } = ta;
|
|
363
365
|
const replyEditorRef = useRef(null);
|
|
364
366
|
const rp = useReply(id, client, cannedResponses, ticketNumber, ticketSubject, fetchAll, handleNextTicket, replyEditorRef);
|
|
365
367
|
const { fileInputRef, replyBody, setReplyBody, replyHtml, setReplyHtml, replyFiles, setReplyFiles, isInternal, setIsInternal, notifyClient, setNotifyClient, sendAsClient, setSendAsClient, sending, showSchedule, setShowSchedule, scheduleDate, setScheduleDate, handleEditorFileUpload, handleCannedSelect, handleReplyFileChange, handleSendReply, handleScheduleReply } = rp;
|
|
@@ -388,6 +390,7 @@ const TicketConversation = () => {
|
|
|
388
390
|
const d = await ticketRes.json();
|
|
389
391
|
setCurrentStatus(d.status || "");
|
|
390
392
|
setSnoozeUntil(d.snoozeUntil || null);
|
|
393
|
+
setAutoCloseScheduledAt(d.autoCloseScheduledAt || null);
|
|
391
394
|
setLastClientReadAt(d.lastClientReadAt || null);
|
|
392
395
|
}
|
|
393
396
|
if (activityRes.ok) {
|
|
@@ -1075,18 +1078,33 @@ const TicketConversation = () => {
|
|
|
1075
1078
|
setShowMerge(!showMerge);
|
|
1076
1079
|
setShowExtMsg(false);
|
|
1077
1080
|
setShowSnooze(false);
|
|
1081
|
+
setShowReminder(false);
|
|
1078
1082
|
},
|
|
1079
1083
|
onToggleExtMsg: () => {
|
|
1080
1084
|
setShowExtMsg(!showExtMsg);
|
|
1081
1085
|
setShowMerge(false);
|
|
1082
1086
|
setShowSnooze(false);
|
|
1087
|
+
setShowReminder(false);
|
|
1083
1088
|
},
|
|
1084
1089
|
onToggleSnooze: () => {
|
|
1085
1090
|
setShowSnooze(!showSnooze);
|
|
1086
1091
|
setShowMerge(false);
|
|
1087
1092
|
setShowExtMsg(false);
|
|
1093
|
+
setShowReminder(false);
|
|
1088
1094
|
},
|
|
1089
1095
|
onNextTicket: handleNextTicket,
|
|
1096
|
+
showReminderButton: features.autoClose,
|
|
1097
|
+
onToggleReminder: () => {
|
|
1098
|
+
setShowReminder(!showReminder);
|
|
1099
|
+
setReminderError("");
|
|
1100
|
+
setShowMerge(false);
|
|
1101
|
+
setShowExtMsg(false);
|
|
1102
|
+
setShowSnooze(false);
|
|
1103
|
+
},
|
|
1104
|
+
autoCloseScheduledAt,
|
|
1105
|
+
onCancelScheduledClose: handleCancelScheduledClose,
|
|
1106
|
+
cancelingClose,
|
|
1107
|
+
reminderSuccess,
|
|
1090
1108
|
showNextTicket,
|
|
1091
1109
|
nextTicketId,
|
|
1092
1110
|
nextTicketInfo,
|
|
@@ -1136,7 +1154,19 @@ const TicketConversation = () => {
|
|
|
1136
1154
|
handleExtFileChange
|
|
1137
1155
|
}
|
|
1138
1156
|
),
|
|
1139
|
-
features.snooze && showSnooze && /* @__PURE__ */ jsx(SnoozePanel, { snoozeSaving, handleSnooze })
|
|
1157
|
+
features.snooze && showSnooze && /* @__PURE__ */ jsx(SnoozePanel, { snoozeSaving, handleSnooze }),
|
|
1158
|
+
features.autoClose && showReminder && /* @__PURE__ */ jsx(
|
|
1159
|
+
ReminderPanel,
|
|
1160
|
+
{
|
|
1161
|
+
clientFirstName: client?.firstName || "",
|
|
1162
|
+
clientEmail: client?.email || "",
|
|
1163
|
+
reminderHours,
|
|
1164
|
+
setReminderHours,
|
|
1165
|
+
reminderSending,
|
|
1166
|
+
reminderError,
|
|
1167
|
+
handleSendReminder
|
|
1168
|
+
}
|
|
1169
|
+
)
|
|
1140
1170
|
] }),
|
|
1141
1171
|
/* @__PURE__ */ jsxs("div", { style: layoutStyles.sideColumn, children: [
|
|
1142
1172
|
/* @__PURE__ */ jsx(
|