@sevenfold/setto-client 0.21.0 → 0.22.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/setto-client.js +108 -8
- package/dist/setto-client.js.map +1 -1
- package/package.json +1 -1
package/dist/setto-client.js
CHANGED
|
@@ -22065,6 +22065,9 @@ function SettoChat() {
|
|
|
22065
22065
|
const [messages, setMessages] = useState([]);
|
|
22066
22066
|
const [draft, setDraft] = useState("");
|
|
22067
22067
|
const [sending, setSending] = useState(false);
|
|
22068
|
+
const [leadOpen, setLeadOpen] = useState(false);
|
|
22069
|
+
const [leadStatus, setLeadStatus] = useState("idle");
|
|
22070
|
+
const [lead, setLead] = useState({ name: "", email: "", phone: "", interest: "", consent: false });
|
|
22068
22071
|
const conversationId = useRef(null);
|
|
22069
22072
|
const visitor = useRef(null);
|
|
22070
22073
|
const logRef = useRef(null);
|
|
@@ -22101,6 +22104,18 @@ function SettoChat() {
|
|
|
22101
22104
|
send: "Send",
|
|
22102
22105
|
sending: "Svarer …",
|
|
22103
22106
|
contact: "Kontakt teamet",
|
|
22107
|
+
followUp: "Be om oppfølging",
|
|
22108
|
+
followUpTitle: "La teamet følge opp",
|
|
22109
|
+
followUpDetail: "Legg igjen kontaktinformasjon hvis du vil at teamet skal følge opp denne samtalen.",
|
|
22110
|
+
name: "Navn",
|
|
22111
|
+
email: "E-post",
|
|
22112
|
+
phone: "Telefon",
|
|
22113
|
+
interest: "Hva vil du ha hjelp med?",
|
|
22114
|
+
consent: "Ja, teamet kan bruke opplysningene mine til å følge opp denne henvendelsen.",
|
|
22115
|
+
leadSend: "Send forespørsel",
|
|
22116
|
+
leadSent: "Takk — forespørselen er sendt til teamet.",
|
|
22117
|
+
leadFailed: "Kunne ikke lagre forespørselen. Prøv igjen eller kontakt teamet direkte.",
|
|
22118
|
+
leadConversation: "Still et spørsmål først, så kan vi knytte oppfølgingen til samtalen.",
|
|
22104
22119
|
failed: "Jeg får ikke svart akkurat nå. Kontakt gjerne teamet direkte."
|
|
22105
22120
|
} : {
|
|
22106
22121
|
open: `Chat with ${settings.displayName}`,
|
|
@@ -22111,6 +22126,18 @@ function SettoChat() {
|
|
|
22111
22126
|
send: "Send",
|
|
22112
22127
|
sending: "Replying …",
|
|
22113
22128
|
contact: "Contact the team",
|
|
22129
|
+
followUp: "Ask for follow-up",
|
|
22130
|
+
followUpTitle: "Let the team follow up",
|
|
22131
|
+
followUpDetail: "Leave contact details if you want the team to follow up on this conversation.",
|
|
22132
|
+
name: "Name",
|
|
22133
|
+
email: "Email",
|
|
22134
|
+
phone: "Phone",
|
|
22135
|
+
interest: "What would you like help with?",
|
|
22136
|
+
consent: "Yes, the team may use my details to follow up on this enquiry.",
|
|
22137
|
+
leadSend: "Send request",
|
|
22138
|
+
leadSent: "Thanks — your request has been sent to the team.",
|
|
22139
|
+
leadFailed: "We could not save your request. Please try again or contact the team directly.",
|
|
22140
|
+
leadConversation: "Ask a question first so we can link the follow-up to this conversation.",
|
|
22114
22141
|
failed: "I cannot reply right now. Please contact the team directly."
|
|
22115
22142
|
};
|
|
22116
22143
|
const submit = async (event) => {
|
|
@@ -22164,6 +22191,34 @@ function SettoChat() {
|
|
|
22164
22191
|
setSending(false);
|
|
22165
22192
|
}
|
|
22166
22193
|
};
|
|
22194
|
+
const submitLead = async (event) => {
|
|
22195
|
+
event.preventDefault();
|
|
22196
|
+
if (leadStatus === "sending") return;
|
|
22197
|
+
if (!conversationId.current || !visitor.current) {
|
|
22198
|
+
setLeadStatus("failed");
|
|
22199
|
+
return;
|
|
22200
|
+
}
|
|
22201
|
+
setLeadStatus("sending");
|
|
22202
|
+
try {
|
|
22203
|
+
const response = await fetch(`${config.apiUrl}/sites/${encodeURIComponent(config.siteId)}/chat/leads`, {
|
|
22204
|
+
method: "POST",
|
|
22205
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
22206
|
+
body: JSON.stringify({
|
|
22207
|
+
conversationId: conversationId.current,
|
|
22208
|
+
visitorId: visitor.current,
|
|
22209
|
+
consent: lead.consent,
|
|
22210
|
+
name: lead.name.trim() || void 0,
|
|
22211
|
+
email: lead.email.trim() || void 0,
|
|
22212
|
+
phone: lead.phone.trim() || void 0,
|
|
22213
|
+
interest: lead.interest.trim() || void 0
|
|
22214
|
+
})
|
|
22215
|
+
});
|
|
22216
|
+
if (!response.ok) throw new Error(`lead_failed_${response.status}`);
|
|
22217
|
+
setLeadStatus("sent");
|
|
22218
|
+
} catch {
|
|
22219
|
+
setLeadStatus("failed");
|
|
22220
|
+
}
|
|
22221
|
+
};
|
|
22167
22222
|
return /* @__PURE__ */ jsxs("aside", { className: "setto-chat", "aria-label": labels.title, "data-setto-ui": true, children: [
|
|
22168
22223
|
open ? /* @__PURE__ */ jsxs("section", { className: "setto-chat__panel", role: "dialog", "aria-modal": "false", "aria-labelledby": `${formId}-title`, children: [
|
|
22169
22224
|
/* @__PURE__ */ jsxs("header", { className: "setto-chat__header", children: [
|
|
@@ -22175,11 +22230,46 @@ function SettoChat() {
|
|
|
22175
22230
|
/* @__PURE__ */ jsx("button", { className: "setto-chat__close", type: "button", onClick: () => setOpen(false), "aria-label": labels.close, children: "×" })
|
|
22176
22231
|
] }),
|
|
22177
22232
|
/* @__PURE__ */ jsx("div", { className: "setto-chat__log", ref: logRef, "aria-live": "polite", children: messages.map((item, index) => /* @__PURE__ */ jsx("div", { className: `setto-chat__message setto-chat__message--${item.role}`, children: item.content || /* @__PURE__ */ jsx("span", { className: "setto-chat__typing", children: "···" }) }, `${item.role}-${index}`)) }),
|
|
22178
|
-
/* @__PURE__ */
|
|
22179
|
-
|
|
22180
|
-
|
|
22181
|
-
|
|
22182
|
-
|
|
22233
|
+
/* @__PURE__ */ jsxs("div", { className: "setto-chat__contact", children: [
|
|
22234
|
+
/* @__PURE__ */ jsxs("button", { type: "button", onClick: contactTeam, children: [
|
|
22235
|
+
labels.contact,
|
|
22236
|
+
" ",
|
|
22237
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "↗" })
|
|
22238
|
+
] }),
|
|
22239
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => {
|
|
22240
|
+
setLeadOpen((value) => !value);
|
|
22241
|
+
setLeadStatus("idle");
|
|
22242
|
+
}, children: labels.followUp })
|
|
22243
|
+
] }),
|
|
22244
|
+
leadOpen ? /* @__PURE__ */ jsxs("form", { className: "setto-chat__lead", onSubmit: submitLead, children: [
|
|
22245
|
+
/* @__PURE__ */ jsx("strong", { children: labels.followUpTitle }),
|
|
22246
|
+
/* @__PURE__ */ jsx("p", { children: labels.followUpDetail }),
|
|
22247
|
+
/* @__PURE__ */ jsxs("div", { className: "setto-chat__lead-grid", children: [
|
|
22248
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
22249
|
+
labels.name,
|
|
22250
|
+
/* @__PURE__ */ jsx("input", { value: lead.name, maxLength: 160, onChange: (event) => setLead((current) => ({ ...current, name: event.target.value })) })
|
|
22251
|
+
] }),
|
|
22252
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
22253
|
+
labels.email,
|
|
22254
|
+
/* @__PURE__ */ jsx("input", { type: "email", value: lead.email, maxLength: 320, onChange: (event) => setLead((current) => ({ ...current, email: event.target.value })) })
|
|
22255
|
+
] }),
|
|
22256
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
22257
|
+
labels.phone,
|
|
22258
|
+
/* @__PURE__ */ jsx("input", { type: "tel", value: lead.phone, maxLength: 64, onChange: (event) => setLead((current) => ({ ...current, phone: event.target.value })) })
|
|
22259
|
+
] }),
|
|
22260
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
22261
|
+
labels.interest,
|
|
22262
|
+
/* @__PURE__ */ jsx("input", { value: lead.interest, maxLength: 500, onChange: (event) => setLead((current) => ({ ...current, interest: event.target.value })) })
|
|
22263
|
+
] })
|
|
22264
|
+
] }),
|
|
22265
|
+
/* @__PURE__ */ jsxs("label", { className: "setto-chat__consent", children: [
|
|
22266
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: lead.consent, onChange: (event) => setLead((current) => ({ ...current, consent: event.target.checked })) }),
|
|
22267
|
+
labels.consent
|
|
22268
|
+
] }),
|
|
22269
|
+
leadStatus === "sent" ? /* @__PURE__ */ jsx("p", { className: "setto-chat__lead-success", children: labels.leadSent }) : null,
|
|
22270
|
+
leadStatus === "failed" ? /* @__PURE__ */ jsx("p", { className: "setto-chat__lead-error", children: conversationId.current ? labels.leadFailed : labels.leadConversation }) : null,
|
|
22271
|
+
leadStatus !== "sent" ? /* @__PURE__ */ jsx("button", { type: "submit", disabled: leadStatus === "sending" || !lead.consent || !lead.email.trim() && !lead.phone.trim(), children: leadStatus === "sending" ? labels.sending : labels.leadSend }) : null
|
|
22272
|
+
] }) : null,
|
|
22183
22273
|
/* @__PURE__ */ jsxs("form", { className: "setto-chat__composer", onSubmit: submit, children: [
|
|
22184
22274
|
/* @__PURE__ */ jsx("label", { className: "setto-chat__sr", htmlFor: `${formId}-input`, children: labels.placeholder }),
|
|
22185
22275
|
/* @__PURE__ */ jsx(
|
|
@@ -22229,7 +22319,7 @@ function useChatStyles() {
|
|
|
22229
22319
|
.setto-chat__launcher { border: 0; min-height: 54px; max-width: min(290px, calc(100vw - 32px)); border-radius: 999px; padding: 8px 18px 8px 9px; display: flex; align-items: center; gap: 10px; background: #251d16; color: #fff9ef; box-shadow: 0 14px 40px rgba(35,29,23,.28); font: 600 14px/1 Archivo, ui-sans-serif, sans-serif; cursor: pointer; transition: transform .18s ease, box-shadow .18s ease; }
|
|
22230
22320
|
.setto-chat__launcher:hover { transform: translateY(-2px); box-shadow: 0 18px 46px rgba(35,29,23,.36); }
|
|
22231
22321
|
.setto-chat__launcher-mark { width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; background: #df6540; color: #fff8eb; font-size: 18px; }
|
|
22232
|
-
.setto-chat__panel { width: min(390px, calc(100vw - 32px)); height: min(590px, calc(100dvh - 104px)); margin-bottom: 12px; overflow: hidden; display: grid; grid-template-rows: auto 1fr auto auto; border: 1px solid rgba(37,29,22,.15); border-radius: 20px; background: #fffaf1; box-shadow: 0 22px 70px rgba(35,29,23,.3); }
|
|
22322
|
+
.setto-chat__panel { width: min(390px, calc(100vw - 32px)); height: min(590px, calc(100dvh - 104px)); margin-bottom: 12px; overflow: hidden; display: grid; grid-template-rows: auto 1fr auto auto auto; border: 1px solid rgba(37,29,22,.15); border-radius: 20px; background: #fffaf1; box-shadow: 0 22px 70px rgba(35,29,23,.3); }
|
|
22233
22323
|
.setto-chat__header { padding: 20px 20px 16px; display: flex; justify-content: space-between; gap: 14px; border-bottom: 1px solid #eadfce; background: radial-gradient(circle at 0 0, #f4d4a9, transparent 52%), #fffaf1; }
|
|
22234
22324
|
.setto-chat__eyebrow { margin: 0 0 4px; color: #b54628; font-size: 10px; font-weight: 700; letter-spacing: .14em; }
|
|
22235
22325
|
.setto-chat__header h2 { margin: 0; color: #211a14; font-family: "Instrument Serif", Georgia, serif; font-size: 29px; font-weight: 400; line-height: 1; }
|
|
@@ -22241,15 +22331,25 @@ function useChatStyles() {
|
|
|
22241
22331
|
.setto-chat__message--visitor { align-self: flex-end; background: #2b221b; color: #fffaf1; border-bottom-right-radius: 3px; }
|
|
22242
22332
|
.setto-chat__typing { display: inline-block; min-width: 24px; animation: setto-chat-pulse 1.1s ease-in-out infinite; letter-spacing: 2px; }
|
|
22243
22333
|
@keyframes setto-chat-pulse { 50% { opacity: .3; } }
|
|
22244
|
-
.setto-chat__contact { padding: 0 18px 12px; }
|
|
22334
|
+
.setto-chat__contact { padding: 0 18px 12px; display: flex; gap: 14px; flex-wrap: wrap; }
|
|
22245
22335
|
.setto-chat__contact button { border: 0; padding: 0; background: transparent; color: #b54628; font: 600 12px/1.4 Archivo, ui-sans-serif, sans-serif; cursor: pointer; }
|
|
22336
|
+
.setto-chat__lead { display: grid; gap: 8px; max-height: 255px; overflow: auto; padding: 12px 18px; border-top: 1px solid #eadfce; background: #fff7ed; font-size: 12px; line-height: 1.4; }
|
|
22337
|
+
.setto-chat__lead p { margin: 0; color: #70665a; }
|
|
22338
|
+
.setto-chat__lead-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
|
|
22339
|
+
.setto-chat__lead label { display: grid; gap: 3px; color: #5f5347; font-weight: 600; }
|
|
22340
|
+
.setto-chat__lead input:not([type="checkbox"]) { width: 100%; border: 1px solid #d8ccba; border-radius: 7px; background: #fffdf8; color: #231d17; padding: 7px; font: 13px Archivo, ui-sans-serif, sans-serif; }
|
|
22341
|
+
.setto-chat__lead .setto-chat__consent { grid-template-columns: auto 1fr; align-items: start; font-weight: 400; }
|
|
22342
|
+
.setto-chat__lead button { justify-self: start; min-height: 34px; border: 0; border-radius: 8px; padding: 0 12px; background: #b54628; color: #fffaf1; font: 600 12px Archivo, ui-sans-serif, sans-serif; cursor: pointer; }
|
|
22343
|
+
.setto-chat__lead button:disabled { opacity: .5; cursor: default; }
|
|
22344
|
+
.setto-chat__lead-success { color: #30683d !important; font-weight: 600; }
|
|
22345
|
+
.setto-chat__lead-error { color: #9b2f1e !important; font-weight: 600; }
|
|
22246
22346
|
.setto-chat__composer { padding: 12px; display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 8px; border-top: 1px solid #eadfce; background: #fffdf8; }
|
|
22247
22347
|
.setto-chat__composer textarea { width: 100%; max-height: 100px; resize: none; border: 1px solid #d8ccba; border-radius: 10px; background: #fffaf1; color: #231d17; padding: 10px; font: 14px/1.35 Archivo, ui-sans-serif, sans-serif; outline: none; }
|
|
22248
22348
|
.setto-chat__composer textarea:focus { border-color: #b54628; box-shadow: 0 0 0 3px rgba(181,70,40,.12); }
|
|
22249
22349
|
.setto-chat__composer button { min-height: 40px; border: 0; border-radius: 9px; padding: 0 13px; background: #b54628; color: #fffaf1; font: 600 13px Archivo, ui-sans-serif, sans-serif; cursor: pointer; }
|
|
22250
22350
|
.setto-chat__composer button:disabled { opacity: .5; cursor: default; }
|
|
22251
22351
|
.setto-chat__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
|
|
22252
|
-
@media (max-width: 480px) { .setto-chat { right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); } .setto-chat__panel { width: calc(100vw - 24px); height: min(610px, calc(100dvh - 88px)); } .setto-chat__launcher { min-height: 50px; } }
|
|
22352
|
+
@media (max-width: 480px) { .setto-chat { right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); } .setto-chat__panel { width: calc(100vw - 24px); height: min(610px, calc(100dvh - 88px)); } .setto-chat__launcher { min-height: 50px; } .setto-chat__lead-grid { grid-template-columns: 1fr; } }
|
|
22253
22353
|
@media (prefers-reduced-motion: reduce) { .setto-chat *, .setto-chat *::before, .setto-chat *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; } }
|
|
22254
22354
|
`;
|
|
22255
22355
|
document.head.appendChild(style);
|