react-native-surveys
Version:
Build your own forms, surveys and polls for your React Native apps.
193 lines (170 loc) • 4.99 kB
JavaScript
import React, { useState, memo, Fragment, useEffect } from "react";
import { Platform } from "react-native";
import {
inIframe,
getParentURL,
SENDING_STATUS,
PREVIEW_STATUS,
TEMPLATE_STATUS,
COMPLETE_STATUS,
ERROR_STATUS,
SENDING_STATUSES_ARRAY,
SOURCE_WEB,
findEmailAndName,
SOURCE_REACT_NATIVE,
addExtraDataToForm
} from "./helpers";
import StatusScreen from "./components/StatusScreen";
import FormContainer from "./components/FormContainer";
import { Toast } from "./components/Toast/Toast";
import ToastWrapper from "./components/Toast/ToastWrapper";
import { getSenderLocation, sendCompletedForm } from "./api/nativeforms-api";
import { getBrowser, getOperatingSystem, queryStringToJSON } from "./utils";
import { returnFormData } from "./blocks/helpers";
import { form_send } from "./api/event-emitter";
const queryParameters = queryStringToJSON();
const Forms = ({
form = {},
preview,
livePreview,
editMode,
isTemplate,
onSend,
onBeforeSend,
iframe,
onClose,
showError
}) => {
const { customer, label } = form;
const isPreview = preview;
const [sendingError, setSendingError] = useState(false);
const [sendingStatus, setSendingStatus] = useState("");
useEffect(() => {
if (showError) showError(false);
setSendingError(false);
setSendingStatus("");
}, [form, showError]);
useEffect(() => {
if (window.INTERCOM_MESSENGER_SHEET_LIBRARY) {
window.INTERCOM_MESSENGER_SHEET_LIBRARY.setTitle(label || "NativeForms");
}
if (!isPreview && !isTemplate && !livePreview && !editMode) {
if (window && window.document) {
window.document.title = label || "NativeForms";
}
}
}, [editMode, isPreview, isTemplate, label, livePreview]);
const closeForm = () => {
if (onClose) onClose();
};
const startForm = () => setSendingStatus("");
const onFormSubmit = async () => {
if (preview) return;
if (setSendingStatus === SENDING_STATUS) return;
if (editMode) {
setSendingStatus(SENDING_STATUS);
await new Promise(r => setTimeout(r, 1000));
setSendingStatus(COMPLETE_STATUS);
return;
}
if (livePreview) {
setSendingStatus(SENDING_STATUS);
await new Promise(r => setTimeout(r, 1000));
setSendingStatus(PREVIEW_STATUS);
return;
}
if (isTemplate) {
setSendingStatus(SENDING_STATUS);
await new Promise(r => setTimeout(r, 1000));
setSendingStatus(TEMPLATE_STATUS);
return;
}
setSendingStatus(SENDING_STATUS);
form.completed = true;
form.completedAt = new Date().toJSON();
form.completedTimestamp = new Date().getTime();
form.browser = getBrowser() || "";
form.source = Platform.OS === "web" ? SOURCE_WEB : SOURCE_REACT_NATIVE;
form.iframe = inIframe() || false;
form.sourceURL = getParentURL() || "";
form.intercom = window.INTERCOM || false;
form.platform =
Platform.OS === "web"
? getOperatingSystem()
: Platform.OS === "ios"
? "iOS"
: "Android";
const { email, name } = findEmailAndName(form);
form.customer = customer || {};
if (email) {
form.customer.email = email;
}
if (name) {
form.customer.name = name;
}
if (!form.customer.email && queryParameters.email) {
form.customer.email = queryParameters.email;
}
if (!form.customer.name && queryParameters.name) {
form.customer.name = queryParameters.name;
}
form.status = "completed";
try {
form.completedLocation = await getSenderLocation();
if (onBeforeSend) {
const extraData = await onBeforeSend(returnFormData(form));
addExtraDataToForm(form, extraData);
}
await sendCompletedForm(form);
setSendingStatus(COMPLETE_STATUS);
const formData = returnFormData(form);
if (onSend) {
onSend(formData);
}
form_send(formData);
} catch (e) {
setSendingStatus(ERROR_STATUS);
console.error(e);
}
};
if (SENDING_STATUSES_ARRAY.includes(sendingStatus)) {
return React.createElement(StatusScreen, {
form: form,
iframe: iframe,
status: sendingStatus,
closeForm: closeForm,
startForm: startForm
});
}
return React.createElement(
Fragment,
null,
React.createElement(FormContainer, {
isPreview: isPreview,
isSending: sendingStatus,
onFormSubmit: onFormSubmit,
setSendingError: showError || setSendingError,
form: form,
iframe: iframe
}),
React.createElement(
ToastWrapper,
{
verticalPosition: "top",
horizontalPosition: "center"
},
sendingError &&
React.createElement(
Toast,
{
variant: "error",
onClose: () => setSendingError(false),
duration: 2000,
removable: true
},
sendingError
)
)
);
};
export default memo(Forms);