UNPKG

@afex-bots/feedback

Version:

Feedback Bot

1,290 lines (1,258 loc) 43.3 kB
// src/components/bot/bot.module.css var bot_default = { dialogContainer: "bot_dialogContainer", dialogContent: "bot_dialogContent" }; // src/components/bot/index.tsx import { ActionIcon as ActionIcon2, Box, deepMerge, Dialog, MantineProvider, Stack as Stack3, Text as Text6 } from "@mantine/core"; import { useState as useState6 } from "react"; // src/libs/config.tsx import { Home3, MessageQuestion, Messages1 } from "iconsax-react"; import { jsx } from "react/jsx-runtime"; var defaultPosition = "bottom-right"; var defaultSections = [ { icon: /* @__PURE__ */ jsx(Home3, { color: "#948A8A", size: "20" }), id: "Home", title: "Home" }, { icon: /* @__PURE__ */ jsx(MessageQuestion, { color: "#948A8A", size: "20" }), id: "Issue", title: "Report an Issue" }, { icon: /* @__PURE__ */ jsx(Messages1, { color: "#948A8A", size: "20" }), id: "Chat", title: "Live Chat" } ]; var defaultSupportGuide = { gradient: ["#ff9e9988", "white"], system: "Exchange", titles: [ { description: "getting started AFEX System", guideSections: [ { heading: "Step 1: Download the App", steps: [ "Head to your app store (Google Play Store or Apple App Store) and search for [App Name].", "Tap the Install button and wait for the app to download." ] }, { heading: "Step 2: Download the App", steps: [ "Open the app and tap on Sign Up.", "Provide your details such as name, email, and a secure password." ] } ], heading: "Getting Started with AFEX System", id: 1 } ] }; var defaultConfiguration = { position: defaultPosition, sections: defaultSections, supportGuide: defaultSupportGuide, icon: /* @__PURE__ */ jsx(MessageQuestion, { color: "#FFFFFF", size: 20, variant: "Bold" }) }; // src/types/index.ts var View = Object.freeze({ Chat: "Chat", Feedback: "Feedback", Home: "Home", Info: "Info", Issue: "Issue" }); // src/components/bot/index.tsx import { useClickOutside } from "@mantine/hooks"; // src/components/faqs/faqs.module.css var faqs_default = { container: "faqs_container", logo: "faqs_logo", heading: "faqs_heading", faqBox: "faqs_faqBox", inputWrapper: "faqs_inputWrapper", inputInner: "faqs_inputInner", supportItem: "faqs_supportItem", feedbackLink: "faqs_feedbackLink" }; // src/components/faqs/index.tsx import { Text, Input } from "@mantine/core"; import { ArrowRight2, SearchNormal1 } from "iconsax-react"; import { useState } from "react"; import { jsx as jsx2, jsxs } from "react/jsx-runtime"; var SupportItem = ({ title, onClick }) => /* @__PURE__ */ jsxs("button", { type: "button", onClick, className: faqs_default.supportItem, children: [ title, " ", /* @__PURE__ */ jsx2(ArrowRight2, { size: "22", color: "#292D32" }) ] }); var FeedbackLink = ({ system, onClick }) => /* @__PURE__ */ jsxs("button", { type: "button", onClick, className: faqs_default.feedbackLink, children: [ "Give ", system, " feedback", /* @__PURE__ */ jsx2(Text, { fz: "md", fw: "normal", children: "Kindly fill the feedback form so we can understand how to serve you better." }) ] }); var Support = ({ supportGuide, navigate }) => { const [searchTerm, setSearchTerm] = useState(""); const filteredFaqs = supportGuide?.titles?.filter( (item) => item.heading.toLowerCase().includes(searchTerm.toLowerCase()) ); return /* @__PURE__ */ jsxs("div", { className: faqs_default.container, children: [ /* @__PURE__ */ jsxs( "svg", { width: "65", height: "20", viewBox: "0 0 65 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [ /* @__PURE__ */ jsx2("title", { children: "AFEXLogo" }), /* @__PURE__ */ jsx2( "path", { d: "M33.1885 0.878906V19.153H45.6607V16.2521H36.3844V11.3517H45.0543V8.45079H36.3844V3.77982H45.6607V0.878906H33.1885Z", fill: "#202020" } ), /* @__PURE__ */ jsx2( "path", { d: "M19.8965 0.878906V19.153H23.1088V11.3517H31.7787V8.45079H23.1088V3.77982H32.3851V0.878906H19.8965Z", fill: "#202020" } ), /* @__PURE__ */ jsx2( "path", { d: "M53.6258 10.0084L46.4473 19.1536H50.6429L55.7072 12.6962L60.7715 19.1536H64.9672C63.4102 17.1705 57.1167 9.15613 55.6908 7.33691L53.593 10.0084H53.6258Z", fill: "#E1261C" } ), /* @__PURE__ */ jsx2( "path", { d: "M55.7238 7.3363L53.626 10.0078L46.4639 0.878906H50.6595L55.7238 7.3363Z", fill: "#202020" } ), /* @__PURE__ */ jsx2( "path", { d: "M65 0.878906L57.8215 10.0078L55.7236 7.3363L60.8043 0.878906H65Z", fill: "#202020" } ), /* @__PURE__ */ jsx2( "path", { d: "M7.80131 0.845703L0 19.1526H3.40898L9.55498 4.71358L12.3739 11.3512H8.63717L7.44075 14.1702H13.5867L15.701 19.1526H19.1099L11.3086 0.845703H7.80131Z", fill: "#202020" } ) ] } ), /* @__PURE__ */ jsxs("h1", { className: faqs_default.heading, children: [ "Welcome to ", supportGuide?.system ] }), supportGuide?.customFaqSection ?? /* @__PURE__ */ jsxs("div", { className: faqs_default.faqBox, children: [ /* @__PURE__ */ jsx2( Input, { classNames: { wrapper: faqs_default.inputWrapper, input: faqs_default.inputInner }, rightSection: /* @__PURE__ */ jsx2(SearchNormal1, { size: 20, color: "#292D32" }), placeholder: "Search for help...", value: searchTerm, onChange: (e) => setSearchTerm(e.currentTarget.value) } ), filteredFaqs?.length ? filteredFaqs.map((item, index) => /* @__PURE__ */ jsx2( SupportItem, { title: item.heading, id: item.id ?? index, onClick: () => navigate("support-info", item.id ?? index) }, item.id ?? index )) : /* @__PURE__ */ jsx2(Text, { fz: "sm", c: "dimmed", mt: "sm", children: "No results found." }) ] }), /* @__PURE__ */ jsx2( FeedbackLink, { system: supportGuide?.system, onClick: () => navigate("feed-back-form") } ) ] }); }; // src/components/faqs/info/info.module.css var info_default = { container: "info_container", backIcon: "info_backIcon", title: "info_title", subtitle: "info_subtitle", contentWrapper: "info_contentWrapper", noInfoText: "info_noInfoText" }; // src/components/faqs/info/index.tsx import { ArrowLeft2 } from "iconsax-react"; import { List, Stack, Text as Text2 } from "@mantine/core"; import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime"; var SupportInfo = ({ lists, onBack, title }) => { return /* @__PURE__ */ jsxs2("div", { className: info_default.container, children: [ /* @__PURE__ */ jsx3( ArrowLeft2, { color: "#292D32", size: 35, onClick: onBack, className: info_default.backIcon } ), /* @__PURE__ */ jsx3("h3", { className: info_default.title, children: title }), /* @__PURE__ */ jsxs2("p", { className: info_default.subtitle, children: [ "Welcome to ", title, "! Let\u2019s get you set up and ready to explore all the amazing features we have to offer." ] }), /* @__PURE__ */ jsxs2("div", { className: info_default.contentWrapper, children: [ /* @__PURE__ */ jsx3(Text2, { className: info_default.noInfoText, children: "No setup information available." }), lists.map((section) => /* @__PURE__ */ jsxs2(Stack, { children: [ /* @__PURE__ */ jsx3(Text2, { fw: "bold", children: section.heading }), /* @__PURE__ */ jsx3(List, { listStyleType: "disc", children: section.steps.map((step) => /* @__PURE__ */ jsx3(List.Item, { children: step }, step)) }) ] }, section.heading)) ] }) ] }); }; // src/components/form/feed-back-form/feed-back-form.module.css var feed_back_form_default = { container: "feed_back_form_container", backArrow: "feed_back_form_backArrow", title: "feed_back_form_title", subtitle: "feed_back_form_subtitle", content: "feed_back_form_content", formGrid: "feed_back_form_formGrid", fullSpan: "feed_back_form_fullSpan", textLeft: "feed_back_form_textLeft", errorText: "feed_back_form_errorText", actions: "feed_back_form_actions", reaction: "feed_back_form_reaction", button: "feed_back_form_button", buttonGray: "feed_back_form_buttonGray", buttonRed: "feed_back_form_buttonRed", feedbackStatus: "feed_back_form_feedbackStatus", emoji: "feed_back_form_emoji" }; // src/components/form/feed-back-form/index.tsx import { ArrowLeft2 as ArrowLeft22 } from "iconsax-react"; import { useState as useState3 } from "react"; // src/components/inputs/button/button.module.css var button_default = { btn: "button_btn", custom_default: "button_custom_default", custom_destructive: "button_custom_destructive", custom_outline: "button_custom_outline", custom_secondary: "button_custom_secondary", custom_ghost: "button_custom_ghost", custom_link: "button_custom_link", custom_default_size: "button_custom_default_size", custom_sm_size: "button_custom_sm_size", custom_lg_size: "button_custom_lg_size", custom_icon_size: "button_custom_icon_size" }; // src/components/inputs/button/index.tsx import { cva } from "class-variance-authority"; import { forwardRef } from "react"; import { jsx as jsx4 } from "react/jsx-runtime"; var buttonVariants = cva(button_default.btn, { variants: { variant: { default: button_default.custom_default, destructive: button_default.custom_destructive, outline: button_default.custom_outline, secondary: button_default.custom_secondary, ghost: button_default.custom_ghost, link: button_default.custom_link }, size: { default: button_default.custom_default_size, sm: button_default.custom_sm_size, lg: button_default.custom_lg_size, icon: button_default.custom_icon_size } }, defaultVariants: { variant: "default", size: "default" } }); var Button = forwardRef( ({ variant, size, ...props }, ref) => { return /* @__PURE__ */ jsx4( "button", { className: buttonVariants({ variant, size }), ref, ...props } ); } ); Button.displayName = "Button"; // src/components/inputs/input/input.module.css var input_default = { input: "input_input", label: "input_label", required: "input_required", error: "input_error" }; // src/components/inputs/input/index.tsx import { forwardRef as forwardRef2 } from "react"; import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime"; var Input2 = forwardRef2( ({ className, type, ...props }, ref) => { return /* @__PURE__ */ jsx5( "input", { className: `${input_default.input} ${className}`, type, ref, ...props } ); } ); Input2.displayName = "Input"; var Label = forwardRef2( ({ className, children, required, ...props }, ref) => { return ( // biome-ignore lint/a11y/noLabelWithoutControl: Composable /* @__PURE__ */ jsxs3("label", { ref, ...props, className: `${input_default.label} ${className}`, children: [ children, required && /* @__PURE__ */ jsx5("span", { className: input_default.required }) ] }) ); } ); Label.displayName = "Label"; var InputError = forwardRef2( ({ showError, message, className, ...props }, ref) => { return showError ? /* @__PURE__ */ jsx5("span", { ref, ...props, className: `${input_default.error} ${className}`, children: message }) : null; } ); InputError.displayName = "Input Error"; // src/components/inputs/select/select.module.css var select_default = { select: "select_select" }; // src/components/inputs/select/index.tsx import { forwardRef as forwardRef3 } from "react"; import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime"; var Select = forwardRef3( ({ className, onChange, options, placeholder, value, ...props }, ref) => { return /* @__PURE__ */ jsxs4( "select", { ref, value, className: `${select_default.select} ${className}`, onChange: (e) => onChange?.(e.target.value), ...props, children: [ placeholder && /* @__PURE__ */ jsx6("option", { value: "", children: placeholder }), options.map((option) => /* @__PURE__ */ jsx6("option", { value: option.value, children: option.label }, option.value)) ] } ); } ); Select.displayName = "Select"; // src/components/inputs/text-editor/text-editor.module.css var text_editor_default = { container: "text_editor_container", label: "text_editor_label", editor: "text_editor_editor", toolbarButton: "text_editor_toolbarButton", hiddenFileInput: "text_editor_hiddenFileInput" }; // src/components/inputs/text-editor/index.tsx import Editor, { BtnBold, BtnBulletList, BtnClearFormatting, BtnItalic, BtnLink, BtnNumberedList, BtnStyles, BtnUnderline, Toolbar } from "react-simple-wysiwyg"; import { useEffect, useRef, useState as useState2 } from "react"; import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime"; function RichTextEditorComponent({ label, name = "", onChange, placeholder = "Start typing...", value = "" }) { const [editorValue, setEditorValue] = useState2(value); const fileInputRef = useRef(null); useEffect(() => { setEditorValue(value); }, [value]); const handleEditorChange = (event) => { const newValue = event.target.value; setEditorValue(newValue); onChange?.(newValue); }; const handleImageSelect = () => { if (fileInputRef.current) { fileInputRef.current.click(); } }; const handleFileChange = (e) => { const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = () => { const imageUrl = reader.result; const imageHtml = `<img src="${imageUrl}" alt="uploaded-image" style="max-width:100%; height:auto; margin:8px 0;" />`; const updatedContent = editorValue + imageHtml; setEditorValue(updatedContent); onChange?.(updatedContent); }; reader.readAsDataURL(file); } e.target.value = ""; }; return /* @__PURE__ */ jsxs5("div", { className: text_editor_default.container, children: [ label && /* @__PURE__ */ jsx7("p", { children: label }), /* @__PURE__ */ jsx7( Editor, { value: editorValue, className: text_editor_default.editor, name, onChange: handleEditorChange, placeholder, children: /* @__PURE__ */ jsxs5(Toolbar, { children: [ /* @__PURE__ */ jsx7(BtnBold, {}), /* @__PURE__ */ jsx7(BtnItalic, {}), /* @__PURE__ */ jsx7(BtnBulletList, {}), /* @__PURE__ */ jsx7(BtnUnderline, {}), /* @__PURE__ */ jsx7(BtnLink, {}), /* @__PURE__ */ jsx7(BtnNumberedList, {}), /* @__PURE__ */ jsx7(BtnStyles, {}), /* @__PURE__ */ jsx7(BtnClearFormatting, {}), /* @__PURE__ */ jsx7( "button", { className: text_editor_default.toolbarButton, onClick: handleImageSelect, title: "Insert Image", children: "\u{1F4F7}" } ), /* @__PURE__ */ jsx7( "input", { accept: "image/*", onChange: handleFileChange, ref: fileInputRef, style: { display: "none" }, type: "file" } ) ] }) } ) ] }); } // src/libs/extract-user-data.ts var extractUserData = (authStatus) => { if (!authStatus || !authStatus.strategy) return { name: "", email: "" }; if (authStatus.strategy === "user-specified") { return authStatus.userData; } let storage; switch (authStatus.strategy) { case "sessionStorage": storage = sessionStorage; break; default: storage = localStorage; break; } try { if (authStatus.method === "string") { return { email: storage.getItem(authStatus.userKeys.email) || "", name: storage.getItem(authStatus.userKeys.name) || "" }; } if (authStatus.method === "object" && authStatus.objectName) { const userObjectRaw = storage.getItem(authStatus.objectName); if (!userObjectRaw) return { email: "", name: "" }; const parsed = JSON.parse(userObjectRaw); return { email: parsed[authStatus.userKeys.email] || "", name: parsed[authStatus.userKeys.name] || "" }; } } catch (err) { console.error("Error extracting user data:", err); } return { email: "", name: "" }; }; // src/components/form/feed-back-form/index.tsx import { Group, Text as Text3 } from "@mantine/core"; import { useForm } from "@mantine/form"; import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime"; var FeedBackForm = ({ apiKey, apiURL, authStatus, headers, onBack, supportGuide }) => { const userData = extractUserData(authStatus); const [loading, setLoading] = useState3(false); const [error, setError] = useState3(""); const [success, setSuccess] = useState3(""); const form = useForm({ initialValues: { email: userData?.email ?? "", first_name: userData?.name ?? "", last_name: "", message: "", rating: "", subject: "" }, validate: { email: (value) => /^\S+@\S+$/.test(value.trim()) ? null : "Invalid email", first_name: (value) => !value.trim() ? "First Name is required" : null, message: (value) => !value.trim() ? "Message is required" : null, subject: (value) => !value.trim() ? "Subject is required" : null } }); const isSelected = (rating) => form.values.rating === rating; const onRate = (rating) => () => form.setFieldValue("rating", isSelected(rating) ? "" : rating); const handleSubmit = async (values) => { setError(""); setSuccess(""); setLoading(true); try { const response = await fetch(`${apiURL}`, { body: JSON.stringify({ email: values.email, message: values.message, name: `${values.first_name} ${values.last_name}`.trim(), subject: values.subject, system: supportGuide?.system, topicId: 17 }), headers: { "Content-Type": "application/json", "X-API-Key": `${apiKey}`, ...headers }, method: "POST" }); if (response.ok) { setSuccess("Your issue has been reported successfully!"); form.reset(); setTimeout(() => { setSuccess(""); }, 3e3); } else { throw new Error(`Failed with status code ${response.status}`); } } catch (err) { console.error(err); setError("Failed to report the issue. Please try again."); setTimeout(() => { setError(""); }, 3e3); } finally { setLoading(false); } }; return /* @__PURE__ */ jsxs6("div", { className: feed_back_form_default.container, children: [ /* @__PURE__ */ jsx8( ArrowLeft22, { color: "#292D32", size: 35, className: feed_back_form_default.backArrow, onClick: onBack } ), /* @__PURE__ */ jsx8(Text3, { className: feed_back_form_default.title, fw: "bold", children: "Feedback Form" }), /* @__PURE__ */ jsxs6(Text3, { className: feed_back_form_default.subtitle, fz: "xs", children: [ userData?.name, " Kindly fill the feedback form as honestly as possible so we can understand how to serve you better." ] }), /* @__PURE__ */ jsx8("form", { className: feed_back_form_default.formGrid, onSubmit: form.onSubmit(handleSubmit), children: /* @__PURE__ */ jsxs6("div", { className: feed_back_form_default.content, children: [ !userData?.name && /* @__PURE__ */ jsxs6(Group, { children: [ /* @__PURE__ */ jsx8(Label, { required: true, children: "First Name" }), /* @__PURE__ */ jsx8( Input2, { type: "text", placeholder: "Enter first name", className: feed_back_form_default.subtitle, ...form.getInputProps("first_name") } ) ] }), form.errors.first_name && /* @__PURE__ */ jsx8(Text3, { c: "red", fz: "xs", children: form.errors.first_name }), !userData?.name && /* @__PURE__ */ jsxs6(Group, { children: [ /* @__PURE__ */ jsx8(Label, { required: true, children: "Last Name" }), /* @__PURE__ */ jsx8( Input2, { type: "text", placeholder: "Enter last name", className: feed_back_form_default.subtitle, ...form.getInputProps("last_name") } ) ] }), form.errors.last_name && /* @__PURE__ */ jsx8(Text3, { c: "red", fz: "xs", children: form.errors.last_name }), !userData?.email && /* @__PURE__ */ jsxs6(Group, { children: [ /* @__PURE__ */ jsx8(Label, { required: true, children: "Email Address" }), /* @__PURE__ */ jsx8( Input2, { type: "email", placeholder: "Enter email address", className: feed_back_form_default.subtitle, ...form.getInputProps("email") } ) ] }), form.errors.email && /* @__PURE__ */ jsx8(Text3, { c: "red", fz: "xs", children: form.errors.email }), /* @__PURE__ */ jsxs6(Group, { children: [ /* @__PURE__ */ jsx8(Label, { required: true, children: "Subject" }), /* @__PURE__ */ jsx8( Input2, { type: "text", placeholder: "Enter the subject of your feedback", className: feed_back_form_default.subtitle, ...form.getInputProps("subject") } ) ] }), form.errors.subject && /* @__PURE__ */ jsx8(Text3, { c: "red", fz: "xs", children: form.errors.subject }), /* @__PURE__ */ jsxs6(Group, { children: [ /* @__PURE__ */ jsx8(Label, { required: true, children: "Message" }), /* @__PURE__ */ jsx8( RichTextEditorComponent, { name: "message", onChange: (value) => form.setFieldValue("message", value), placeholder: "Enter your feedback message", value: form.values.message } ) ] }), form.errors.message && /* @__PURE__ */ jsx8(Text3, { c: "red", fz: "xs", children: form.errors.message }), /* @__PURE__ */ jsxs6("div", { className: feed_back_form_default.reaction, children: [ /* @__PURE__ */ jsx8( Reaction, { selected: isSelected("Very Bad"), onReact: onRate("Very Bad"), children: "\u{1F621}" } ), /* @__PURE__ */ jsx8(Reaction, { onReact: onRate("Bad"), selected: isSelected("Bad"), children: "\u{1F614}" }), /* @__PURE__ */ jsx8( Reaction, { onReact: onRate("Neutral"), selected: isSelected("Neutral"), children: "\u{1F611}" } ), /* @__PURE__ */ jsx8(Reaction, { onReact: onRate("Good"), selected: isSelected("Good"), children: "\u{1F642}" }), /* @__PURE__ */ jsx8( Reaction, { onReact: onRate("Excellent"), selected: isSelected("Excellent"), children: "\u{1F970}" } ) ] }), /* @__PURE__ */ jsxs6("div", { className: feed_back_form_default.actions, children: [ /* @__PURE__ */ jsx8( Button, { className: `${feed_back_form_default.button} ${feed_back_form_default.buttonGray}`, type: "button", onClick: () => { form.reset(); setError(""); setSuccess(""); }, children: "Cancel" } ), /* @__PURE__ */ jsx8( Button, { className: `${feed_back_form_default.button} ${feed_back_form_default.buttonRed}`, type: "submit", disabled: loading, children: loading ? "Sending..." : "Send" } ) ] }), /* @__PURE__ */ jsxs6("div", { className: feed_back_form_default.feedbackStatus, children: [ error && /* @__PURE__ */ jsx8(Text3, { c: "red", py: 8, children: error }), success && /* @__PURE__ */ jsx8(Text3, { c: "green", py: 8, children: success }) ] }) ] }) }) ] }); }; function Reaction({ children, onReact, selected }) { return /* @__PURE__ */ jsx8( "button", { type: "button", onClick: onReact, "aria-selected": selected, className: feed_back_form_default.emoji, children } ); } // src/components/form/report-an-issue/report-an-issue.module.css var report_an_issue_default = { container: "report_an_issue_container", title: "report_an_issue_title", subtitle: "report_an_issue_subtitle", content: "report_an_issue_content", formGrid: "report_an_issue_formGrid", textLeft: "report_an_issue_textLeft", errorText: "report_an_issue_errorText", actions: "report_an_issue_actions", button: "report_an_issue_button", buttonGray: "report_an_issue_buttonGray", buttonRed: "report_an_issue_buttonRed", feedbackStatus: "report_an_issue_feedbackStatus" }; // src/components/form/report-an-issue/index.tsx import { Group as Group2, Text as Text4 } from "@mantine/core"; import { useForm as useForm2 } from "@mantine/form"; import { useEffect as useEffect2, useState as useState4 } from "react"; // src/libs/issue-types.ts var ISSUE_TYPES = Object.freeze([ { label: "Payment & Account Issues", value: "16" }, { label: "IT Support", value: "14" }, { label: "Feedback", value: "17" }, { label: "AFTL NG", value: "18" }, { label: "Trade", value: "19" }, { label: "Exchange", value: "20" }, { label: "Banking", value: "21" }, { label: "Data", value: "22" }, { label: "General", value: "15" } ]); // src/components/form/report-an-issue/index.tsx import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime"; var ReportAnIssueForm = ({ apiKey, apiURL, authStatus, issueType }) => { const userData = extractUserData(authStatus); const [loading, setLoading] = useState4(false); const [error, setError] = useState4(""); const [success, setSuccess] = useState4(""); const DEFAULT_TYPE_LABELS = [ "Payment & Account Issues", "IT Support", "Feedback", "General" ]; const issueTypes = ISSUE_TYPES.filter((type) => { return DEFAULT_TYPE_LABELS.includes(type.label) || type.label === issueType; }); useEffect2(() => { if (issueType && !ISSUE_TYPES.some((type) => type.label === issueType)) { console.warn( `[ReportAnIssueForm] Invalid additionalIssueType "${issueType}" passed. Check ISSUE_TYPES for valid labels.` ); } }, [issueType]); const form = useForm2({ initialValues: { email: userData?.email ?? "", message: "", name: userData?.name ?? "", subject: "", topicId: "" }, validate: { email: (value) => /^\S+@\S+$/.test(value.trim()) ? null : "Invalid email", message: (value) => !value.trim() ? "Message is required" : null, name: (value) => !value.trim() ? "Name is required" : null, subject: (value) => !value.trim() ? "Subject is required" : null, topicId: (value) => !value ? "Please select an issue type" : null } }); const handleSubmit = async (values) => { setError(""); setSuccess(""); setLoading(true); try { const response = await fetch(`${apiURL}`, { body: JSON.stringify({ ...values }), headers: { "Content-Type": "application/json", "X-API-Key": `${apiKey}` }, method: "POST" }); if (response.ok) { setSuccess("Your issue has been reported successfully!"); form.reset(); setTimeout(() => { setSuccess(""); }, 3e3); } else { throw new Error(`Failed with status code ${response.status}`); } } catch (err) { console.error(err); setError("Failed to report the issue. Please try again."); setTimeout(() => { setError(""); }, 3e3); } finally { setLoading(false); } }; return /* @__PURE__ */ jsxs7("div", { className: report_an_issue_default.container, children: [ /* @__PURE__ */ jsx9(Text4, { fw: "bold", children: "Report an Issue" }), /* @__PURE__ */ jsxs7(Text4, { fz: "xs", children: [ userData?.name, " Kindly fill the form as correctly as possible so we can understand how to help you." ] }), /* @__PURE__ */ jsx9( "form", { className: report_an_issue_default.formGrid, onSubmit: form.onSubmit(handleSubmit), autoComplete: "off", children: /* @__PURE__ */ jsxs7("div", { className: report_an_issue_default.content, children: [ !userData.name && /* @__PURE__ */ jsxs7(Group2, { className: "flex-1", children: [ /* @__PURE__ */ jsx9(Label, { htmlFor: "name", required: true, children: "Name" }), /* @__PURE__ */ jsx9( Input2, { className: report_an_issue_default.subtitle, ...form.getInputProps("name"), placeholder: "Enter your full name" } ), form.errors.name && /* @__PURE__ */ jsx9(Text4, { c: "red", fz: "xs", children: form.errors.name }) ] }), !userData.email && /* @__PURE__ */ jsxs7(Group2, { className: "flex-1", children: [ /* @__PURE__ */ jsx9(Label, { htmlFor: "email", required: true, children: "Email Address" }), /* @__PURE__ */ jsx9( Input2, { className: report_an_issue_default.subtitle, ...form.getInputProps("email"), placeholder: "Enter your email address" } ), form.errors.email && /* @__PURE__ */ jsx9(Text4, { c: "red", fz: "xs", children: form.errors.email }) ] }), /* @__PURE__ */ jsxs7(Group2, { children: [ /* @__PURE__ */ jsx9(Label, { htmlFor: "subject", required: true, children: "Subject" }), /* @__PURE__ */ jsx9( Input2, { className: report_an_issue_default.subtitle, ...form.getInputProps("subject"), placeholder: "Enter the subject of your issue" } ), form.errors.subject && /* @__PURE__ */ jsx9(Text4, { c: "red", fz: "xs", children: form.errors.subject }) ] }), /* @__PURE__ */ jsxs7(Group2, { children: [ /* @__PURE__ */ jsx9(Label, { htmlFor: "topicId", required: true, children: "Issue Type" }), /* @__PURE__ */ jsx9( Select, { id: "topicId", name: "topicId", onChange: (value) => form.setFieldValue("topicId", value), options: issueTypes || [], placeholder: "Select an issue type", value: form.values.topicId } ), form.errors.topicId && /* @__PURE__ */ jsx9(Text4, { c: "red", fz: "xs", children: form.errors.topicId }) ] }), /* @__PURE__ */ jsxs7(Group2, { children: [ /* @__PURE__ */ jsx9(Label, { htmlFor: "message", required: true, children: "Message" }), /* @__PURE__ */ jsx9( RichTextEditorComponent, { name: "message", onChange: (value) => form.setFieldValue("message", value), placeholder: "Enter your message", value: form.values.message } ), form.errors.message && /* @__PURE__ */ jsx9(Text4, { c: "red", fz: "xs", children: form.errors.message }) ] }), /* @__PURE__ */ jsxs7("div", { className: report_an_issue_default.actions, children: [ /* @__PURE__ */ jsx9( Button, { className: `${report_an_issue_default.button} ${report_an_issue_default.buttonGray}`, type: "button", onClick: () => { form.reset(); setError(""); setSuccess(""); }, children: "Cancel" } ), /* @__PURE__ */ jsx9( Button, { className: `${report_an_issue_default.button} ${report_an_issue_default.buttonRed}`, type: "submit", disabled: loading, children: loading ? "Sending..." : "Send" } ) ] }) ] }) } ), /* @__PURE__ */ jsxs7("div", { className: report_an_issue_default.feedbackStatus, children: [ error && /* @__PURE__ */ jsx9(Text4, { mb: 14, c: "red", children: error }), success && /* @__PURE__ */ jsx9(Text4, { mb: 14, c: "green", children: success }) ] }) ] }); }; // src/components/live-chat/index.tsx import Picker from "emoji-picker-react"; // src/components/live-chat/live-chat.module.css var live_chat_default = { wrapper: "live_chat_wrapper", input: "live_chat_input", container: "live_chat_container" }; // src/components/live-chat/index.tsx import { ActionIcon, Center, Input as Input3, Stack as Stack2, Text as Text5 } from "@mantine/core"; import { useForm as useForm3 } from "@mantine/form"; import { Messages, Send2 } from "iconsax-react"; import { useState as useState5 } from "react"; import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime"; function LiveChat() { const form = useForm3({ initialValues: { message: "" } }); const [messages, setMessages] = useState5([]); const [showEmojiPicker, setShowEmojiPicker] = useState5(false); const header = /* @__PURE__ */ jsxs8(Stack2, { align: "center", children: [ /* @__PURE__ */ jsx10(Text5, { fw: 600, fz: 18, inherit: true, children: "Live Chat" }), /* @__PURE__ */ jsx10(Text5, { fz: 14, inherit: true, opacity: 0.6, children: "Messages from the team will be shown here." }) ] }); const emptyContent = /* @__PURE__ */ jsx10(Center, { h: "100%", children: /* @__PURE__ */ jsxs8(Stack2, { align: "center", c: "#686161", maw: 288, children: [ /* @__PURE__ */ jsx10(Messages, { color: "#686161", size: 40, variant: "Outline" }), /* @__PURE__ */ jsx10(Text5, { fw: "bold", fz: 14, ta: "center", children: "Messages from the team will be shown here" }) ] }) }); const handleEmojiSelect = (emojiData) => { const message = form.values.message; form.setFieldValue("message", message + emojiData.emoji); setShowEmojiPicker(false); }; const handleSendMessage = () => { if (form.values.message.trim()) { setMessages((prevMessages) => [...prevMessages, form.values.message]); form.setFieldValue("message", ""); } }; const messageInput = /* @__PURE__ */ jsxs8(Stack2, { mt: 20, children: [ /* @__PURE__ */ jsx10( Input3, { classNames: { wrapper: live_chat_default.wrapper, input: live_chat_default.input }, onChange: (event) => form.setFieldValue("message", event.currentTarget.value), placeholder: "Type a Message", rightSection: /* @__PURE__ */ jsx10( ActionIcon, { bg: "#e2261c", color: "#e2261c", onClick: handleSendMessage, radius: 4, size: 35, variant: "filled", children: /* @__PURE__ */ jsx10(Send2, { color: "#FFFFFF", size: 20, variant: "Bold" }) } ), value: form.values.message } ), showEmojiPicker && /* @__PURE__ */ jsx10("div", { style: { marginTop: "8px" }, children: /* @__PURE__ */ jsx10(Picker, { onEmojiClick: handleEmojiSelect }) }) ] }); return /* @__PURE__ */ jsxs8("div", { className: live_chat_default.container, children: [ header, /* @__PURE__ */ jsxs8( Stack2, { p: "md", style: { display: "flex", flexDirection: "column", flexGrow: 1, justifyContent: "space-between", width: "100%" }, children: [ /* @__PURE__ */ jsxs8(Stack2, { style: { overflowY: "auto", flexGrow: 1, width: "100%" }, children: [ /* @__PURE__ */ jsx10("div", { children: emptyContent }), messages.map((msg) => /* @__PURE__ */ jsx10(Text5, { mb: "xs", children: msg }, msg)) ] }), messageInput ] } ) ] }); } // src/components/navigation/navigation.module.css var navigation_default = { container: "navigation_container", tabsRoot: "navigation_tabsRoot", tab: "navigation_tab", tabLabel: "navigation_tabLabel", tabsList: "navigation_tabsList" }; // src/components/navigation/index.tsx import { Tabs } from "@mantine/core"; import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime"; var Navigation = ({ navigate, sections = defaultConfiguration.sections }) => { return /* @__PURE__ */ jsx11("nav", { className: navigation_default.container, children: /* @__PURE__ */ jsx11( Tabs, { variant: "none", defaultValue: "home", radius: "xl", styles: { root: { display: "flex", flexDirection: "column", justifyContent: "space-between" }, tab: { textAlign: "center", backgroundColor: "transparent", border: "none", justifyContent: "center", alignItems: "center" }, tabLabel: { alignItems: "center", display: "flex", flexDirection: "column", justifyContent: "center", textAlign: "center", gap: "5px" } }, classNames: { tab: navigation_default.tab, list: navigation_default.tabList }, children: /* @__PURE__ */ jsx11(Tabs.List, { children: sections?.map((section) => /* @__PURE__ */ jsx11( Tabs.Tab, { value: section.id, onClick: () => navigate(section.id), hidden: !(section.show ?? true), children: /* @__PURE__ */ jsxs9("div", { children: [ section.icon, section.title ] }) }, section.id )) }) } ) }); }; // src/components/faqs/info/wrapper.tsx import { jsx as jsx12 } from "react/jsx-runtime"; var SupportInfoWrapper = ({ id, onBack, supportGuide }) => { const item = supportGuide?.titles?.find((t) => t.id === id); if (!item) { return /* @__PURE__ */ jsx12("div", { children: "Support info not found." }); } return /* @__PURE__ */ jsx12(SupportInfo, { lists: item.guideSections || [], onBack, title: item.heading }); }; // src/components/bot/index.tsx import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime"; var FeedBackBot = (defaultProps) => { if (!defaultProps.apiKey || !defaultProps.apiURL) { throw new Error("API URL and API key not defined"); } const props = deepMerge(defaultConfiguration, defaultProps); console.log("Feedback Bot Props:", props); const { authStatus, sections, supportGuide } = props; const [dialogOpened, setDialogOpened] = useState6(false); const [currentView, setCurrentView] = useState6( (props?.sections ?? [])[0].id ); const [selectedId, setSelectedId] = useState6(null); const toggleDialog = () => setDialogOpened((prev) => !prev); const ref = useClickOutside(() => setDialogOpened(false)); const goToView = (view, id) => { setSelectedId(id ?? null); setCurrentView(view); }; const viewMap = { [View.Chat]: /* @__PURE__ */ jsx13(LiveChat, {}), [View.Feedback]: /* @__PURE__ */ jsx13( FeedBackForm, { apiKey: props.apiKey, apiURL: props.apiURL, authStatus, onBack: () => setCurrentView(View.Home), supportGuide } ), [View.Home]: /* @__PURE__ */ jsx13( Support, { apiKey: props.apiKey, apiURL: props.apiURL, navigate: (view, id) => { if (view === "support-info" && id !== void 0) { goToView(View.Info, id); } else if (view === "feed-back-form") { goToView(View.Feedback); } }, supportGuide } ), [View.Info]: /* @__PURE__ */ jsx13( SupportInfoWrapper, { id: selectedId, onBack: () => setCurrentView(View.Home), supportGuide } ), [View.Issue]: /* @__PURE__ */ jsx13( ReportAnIssueForm, { apiKey: props.apiKey, apiURL: props.apiURL, authStatus, issueType: supportGuide?.system } ) }; return /* @__PURE__ */ jsxs10(MantineProvider, { children: [ /* @__PURE__ */ jsx13( Dialog, { mb: 40, onClose: toggleDialog, opened: dialogOpened, p: 0, radius: "md", style: { maxWidth: 400, width: "100%" }, withCloseButton: true, ref, classNames: { closeButton: "bg-white rounded-lg mt-2" }, children: /* @__PURE__ */ jsxs10( "div", { className: bot_default.dialogContainer, style: { background: `linear-gradient(to bottom, ${supportGuide?.gradient?.[0]}, transparent 200px)` }, children: [ /* @__PURE__ */ jsx13("div", { className: bot_default.dialogContent, children: viewMap[currentView] }), /* @__PURE__ */ jsx13(Navigation, { sections, navigate: goToView }) ] } ) } ), /* @__PURE__ */ jsx13( ActionIcon2, { onClick: toggleDialog, radius: 4, size: 40, style: { backgroundColor: "#e2261c", bottom: "20px", position: "fixed", right: "20px", zIndex: 1e3 }, variant: "filled", children: /* @__PURE__ */ jsxs10(Stack3, { gap: 0, mx: "auto", children: [ /* @__PURE__ */ jsx13(Box, { w: "fit-content", mx: "auto", children: props.icon }), typeof props.label === "string" ? /* @__PURE__ */ jsx13(Text6, { fz: 8, fw: 700, ta: "center", children: props.label }) : props.label ] }) } ) ] }); }; export { FeedBackBot, defaultPosition, defaultSections, defaultSupportGuide }; //# sourceMappingURL=index.js.map