fm-lp-factory
Version:
package created to build web ui components for FidelizarMais LP services
470 lines (419 loc) • 19.6 kB
JavaScript
import flat from "../../../assets/components/icons/flat.js";
import rounded from "../../../assets/components/icons/rounded.js";
import { basicArrowSpinningLoading } from "../../../assets/components/loaders.js";
import { updateFmTemplateCss } from "../index.js";
let componentData = {
userDocument: null,
indicationCode: null,
whatsappIndicationText: null,
}
const componentTexts = {
getIndicationCodeBtn: "Consultar",
sendIndicationBtn: "Indicar",
getIndicationCodeWrongDocument: '<span style="color:red;">Informe um CPF ou CNPJ válido</span>',
getIndicationCodeSuccess: `Cupom de indicação gerado com sucesso <strong>%indicationCode%</strong>`,
getIndicationCodeGenericError: '<span style="color:red;">Erro ao gerar cupom de indicação</span>',
sendIndicationWhatsAppSuccess: "Indicação enviada com sucesso!",
sendIndicationWhatsAppError: '<span style="color:red;">Informe um número de telefone válido</span>',
sendIndicationEmailSuccess: "Indicação enviada com sucesso!",
sendIndicationEmailError: '<span style="color:red;">Informe um e-mail válido</span>',
}
export default (component) => {
const section = document.createElement('section');
css();
section.className = 'fm-section-container fm-indication-component';
componentData.whatsappIndicationText = component.configuration.indicateByWhatsapp.indicationText;
Promise.all([
flat.whatsappFlat(),
rounded.whatsappRounded(),
rounded.emailIconRounded(),
flat.emailIconFlat()
]).then(([whatsappFlat, whatsappRounded, emailIconRounded, emailIconFlat]) => {
section.innerHTML = template
.replace("%title%", component.title || "Indicação")
.replace("%subtitle%", component.subtitle || "Indique e ganhe")
.replace("%waysToIndicate%", waysToIndicate(component.configuration))
.replace("%componentGetIndicationCodeBtn%", componentTexts.getIndicationCodeBtn)
.replace("%whatsAppIcon%", whatsappFlat)
.replace("%whatsAppIconRounded%", whatsappRounded)
.replace("%emailIconRounded%", emailIconRounded)
.replace("%emailIcon%", emailIconFlat)
.replaceAll("%sendIndicationBtn%", componentTexts.sendIndicationBtn);
resolvePromises(section, component);
});
document.querySelector("#fm-landing-page-content").appendChild(section);
}
const getIndicationCode = async (btnAction) => {
const parent = btnAction.closest(".fm-indication-component");
const alert = parent.querySelector(".fm-alert.document-forms");
const indicationBtns = parent.querySelectorAll(".fm-indication-models-btn");
alert.innerHTML = "";
alert.classList.remove("active", "success", "error");
if (!componentData.userDocument || !LoyalJS.public.utils().validation.isValidCPForCNPJ(componentData.userDocument)) {
alert.innerHTML = componentTexts.getIndicationCodeWrongDocument;
}
else try {
btnAction.innerHTML = basicArrowSpinningLoading;
const responseGetIndicationCode = await LoyalJS.public.services().gamification.sendIndicationGamification(componentData.userDocument);
if (responseGetIndicationCode.body.success) {
componentData.indicationCode = responseGetIndicationCode.body.data.coupon;
indicationBtns.forEach((btn) => {
btn.classList.remove("disabled");
btn.removeAttribute("disabled");
});
alert.innerHTML = componentTexts.getIndicationCodeSuccess
.replace("%indicationCode%", componentData.indicationCode);
}
else alert.innerHTML = responseGetIndicationCode.body.message;
} catch (error) {
console.log(error);
alert.innerHTML = componentTexts.sendIndicationWhatsAppError;
}
btnAction.innerHTML = componentTexts.getIndicationCodeBtn;
alert.classList.add("active");
}
const sendWhatsAppIndication = async (btnAction) => {
const parent = btnAction.closest(".fm-indication-modal-content");
const alert = parent.querySelector(".fm-alert.whatsapp-modal");
const input = parent.querySelector("input");
alert.innerHTML = "";
alert.classList.remove("active", "success", "error");
if (!LoyalJS.public.utils().validation.isValidCellphone(input.value)) {
alert.innerHTML = componentTexts.sendIndicationWhatsAppError;
alert.classList.add("active", "error");
} else try {
btnAction.innerHTML = basicArrowSpinningLoading;
const responseSendWhatsAppIndication = await LoyalJS.public.services().gamification.indicateByWhatsapp(
{
coupon: componentData.indicationCode,
cellphone: input.value,
document: componentData.userDocument,
accountManager: componentData.userDocument,
}
);
if (responseSendWhatsAppIndication.body.success) {
let whatsAppNumber;
if (LoyalJS.settings.lang == 'pt-BR') whatsAppNumber = `+55${input.value}`;
else whatsAppNumber = `${input.value}`;
if (componentData.whatsappIndicationText) {
const whatsAppMessageWithCoupon = decodeURIComponent(componentData.whatsappIndicationText).replace('%cupom%', componentData.indicationCode);
window.open(
encodeURI(`https://api.whatsapp.com/send?phone=${whatsAppNumber}&text=${whatsAppMessageWithCoupon}`)
, '_blank'
)
}
else window.open(`https://api.whatsapp.com/send/?phone=${whatsAppNumber}&text=Use meu código ${componentData.indicationCode} para ganhar desconto na sua compra!`, '_blank');
alert.innerHTML = componentTexts.sendIndicationWhatsAppSuccess;
alert.classList.add("success");
}
else {
alert.innerHTML = responseSendWhatsAppIndication.body.message;
alert.classList.add("error");
}
} catch (error) {
console.log(error);
alert.innerHTML = componentTexts.getIndicationCodeGenericError;
alert.classList.add("error");
}
btnAction.innerHTML = componentTexts.sendIndicationBtn;
alert.classList.add("active");
}
const sendEmailIndication = async (btnAction) => {
const parent = btnAction.closest(".fm-indication-modal-content");
const alert = parent.querySelector(".fm-alert.email-modal");
const input = parent.querySelector("input");
alert.innerHTML = "";
alert.classList.remove("active", "success", "error");
if (!LoyalJS.public.utils().validation.isValidEmail(input.value)) {
alert.innerHTML = componentTexts.sendIndicationEmailError;
alert.classList.add("active", "error");
} else try {
btnAction.innerHTML = basicArrowSpinningLoading;
const responseSendEmailIndication = await LoyalJS.public.services().gamification.indicateByEmail(
{
coupon: componentData.indicationCode,
email: input.value,
document: componentData.userDocument,
accountManager: componentData.userDocument,
}
);
if (responseSendEmailIndication.body.success) {
alert.innerHTML = componentTexts.sendIndicationEmailSuccess;
alert.classList.add("success");
}
else {
alert.innerHTML = responseSendEmailIndication.body.message;
alert.classList.add("error");
}
} catch (error) {
alert.innerHTML = componentTexts.getIndicationCodeGenericError;
alert.classList.add("error");
}
btnAction.innerHTML = componentTexts.sendIndicationBtn;
alert.classList.add("active");
}
const template = /*html*/ `
<div class="fm-flex-center fm-indication-component-inner">
<div class="indication-left-container">
<strong class="fm-h3">%title%</strong>
<p>%subtitle%</p>
%waysToIndicate%
</div>
<div class="indication-card">
<div>
<strong class="fm-h3">Área de indicação</strong>
<p style="margin: 0 0 15px 0;">Consulte seu cupom de indicação preenchendo o campo</p>
<form class="fm-lp-input-container" fm-action="getIndicationCodeSubmit">
<input fm-data="document" autocomplete="username" class="fm-input-text fm-mask-cpf-cnpj" type="text"
maxlength="18" placeholder="Informe seu CPF ou CNPJ" >
<div class="fm-button-container" fm-action="getIndicationCodeClick">
<span>%componentGetIndicationCodeBtn%</span>
</div>
</form>
</div>
<div class="fm-indication-models-btn-container">
<div fm-content="whatsApp">
<div fm-action="openIndicationWhatsAppModal" class="fm-indication-models-btn fm-button disabled" disabled>
%whatsAppIcon%
Indicar via WhatsApp
</div>
<div class="fm-indication-modal whatsapp-modal">
<div class="fm-indication-modal-content">
<span class="fm-indication-modal-close" fm-action="closeModal">×</span>
<div class="fm-indication-modal-content-body">
%whatsAppIconRounded%
<p class="title">Indicar através do WhatsApp</p>
<p>Para fazer sua indicação digite o número no campo indicado abaixo.</p>
<form class="fm-lp-input-container" fm-action="indicateByWhatsappSubmit">
<input fm-data="document" autocomplete="username" class="fm-input-text fm-mask-mobilephone"
type="text" maxlength="18" placeholder="Informe o número de telefone" >
<div class="fm-button-container" fm-action="indicateByWhatsappClick">
<span>%sendIndicationBtn%</span>
</div>
</form>
<div class="fm-alert whatsapp-modal"> </div>
</div>
</div>
</div>
</div>
<div fm-content="email">
<div fm-action="openIndicationEmailModal" class="fm-indication-models-btn fm-button disabled" disabled>
%emailIcon%
Indicar via email
</div>
<div class="fm-indication-modal email-modal">
<div class="fm-indication-modal-content">
<span class="fm-indication-modal-close" fm-action="closeModal">×</span>
<div class="fm-indication-modal-content-body">
%emailIconRounded%
<p class="title">Indicar através do e-mail</p>
<p>Para fazer sua indicação digite o email no campo indicado abaixo.</p>
<form class="fm-lp-input-container" fm-action="indicateByEmailSubmit">
<input fm-data="document" autocomplete="username" class="fm-input-text "
type="email" placeholder="Digite aqui o e-mail do seu amigo">
<div class="fm-button-container" fm-action="indicateByEmailClick">
<span>%sendIndicationBtn%</span>
</div>
</form>
<div class="fm-alert email-modal"> </div>
</div>
</div>
</div>
</div>
</div>
<div class="fm-alert document-forms"> </div>
</div>
</div>
`;
const waysToIndicateTemplate = /*html*/ `
<div class="fm-ways-to-indicate-container">
<h3>Quais são as formas de indicação?</h3>
%waysToIndicate%
</div>
`;
const typeOfIndicationTemplate = /*html*/ `
<strong>%title%</strong>
<p>%subtitle%</p>
`;
const waysToIndicate = (indicationConfig) => {
const ways = [];
if (indicationConfig.indicateByWhatsapp.active) {
ways.push(typeOfIndicationTemplate
.replace("%title%", indicationConfig.indicateByWhatsapp.title)
.replace("%subtitle%", indicationConfig.indicateByWhatsapp.subtitle)
);
}
if (indicationConfig.indicateByEmail.active) {
ways.push(typeOfIndicationTemplate
.replace("%title%", indicationConfig.indicateByEmail.title)
.replace("%subtitle%", indicationConfig.indicateByEmail.subtitle)
);
}
return waysToIndicateTemplate.replace("%waysToIndicate%", ways.join(""));
}
const resolvePromises = (section, component) => {
if (!component.configuration.indicateByWhatsapp.active)
section.querySelector("[fm-content='whatsApp']").style.display = "none";
if (!component.configuration.indicateByEmail.active)
section.querySelector("[fm-content='email']").style.display = "none";
section.querySelector("[fm-action='getIndicationCodeSubmit']").addEventListener("submit", (event) => {
event.preventDefault();
getIndicationCode(event.target.querySelector("[fm-action='getIndicationCodeClick']"));
});
section.querySelector("[fm-action='getIndicationCodeClick']").addEventListener("click", (event) => {
getIndicationCode(event.target);
});
section.querySelector("[fm-action='openIndicationWhatsAppModal']").addEventListener("click", (event) => {
section.querySelector(".whatsapp-modal").style.display = "block";
});
section.querySelector("[fm-action='openIndicationEmailModal']").addEventListener("click", (event) => {
section.querySelector(".email-modal").style.display = "block";
});
section.querySelector("[fm-data='document']").addEventListener("input", (event) => {
componentData.userDocument = event.target.value;
});
section.querySelectorAll("[fm-action='closeModal']").forEach((element) => {
element.addEventListener("click", (event) => {
const btn = event.target;
const modal = btn.closest(".fm-indication-modal");
modal.style.display = "none";
});
});
section.querySelector("[fm-action='indicateByWhatsappClick']").addEventListener("click", (event) => {
sendWhatsAppIndication(event.target);
});
section.querySelector("[fm-action='indicateByWhatsappSubmit']").addEventListener("submit", (event) => {
event.preventDefault();
sendWhatsAppIndication(event.target.querySelector("[fm-data]"));
});
section.querySelector("[fm-action='indicateByEmailClick']").addEventListener("click", (event) => {
sendEmailIndication(event.target);
});
section.querySelector("[fm-action='indicateByEmailSubmit']").addEventListener("submit", (event) => {
event.preventDefault();
sendEmailIndication(event.target.querySelector("[fm-data]"));
});
}
const css = () => {
updateFmTemplateCss( /*css*/ `
.fm-indication-component .indication-left-container {
text-align: left;
flex-basis: 50%;
}
.fm-indication-component .indication-card {
background: var(--fm-secondary-light-color);
padding: 20px;
border-radius: var(--fm-base-border-radius);
}
.fm-indication-component .indication-card .fm-indication-models-btn-container {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin: 20px 0;
}
.fm-indication-component .indication-card .fm-indication-models-btn-container [fm-content] {
display: flex;
flex-direction: column;
}
.fm-indication-component .indication-card .fm-indication-models-btn-container [fm-content] .fm-indication-models-btn svg{
width:25px;
fill: currentColor;
}
.fm-indication-component .indication-card .fm-indication-models-btn {
border-radius: var(--fm-base-border-radius);
background: var(--fm-secondary-button-color);
color: var(--fm-secondary-button-text-color);
padding: 10px;
cursor: pointer;
display: flex;
justify-content: space-evenly;
align-items: center;
text-align: center;
gap: 10px;
}
.fm-indication-component .indication-card .fm-indication-models-btn[disabled] {
cursor: not-allowed;
pointer-events: none;
opacity: 0.1;
}
.fm-indication-modal{
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgb(0 0 0 / 37%);
}
.fm-indication-modal .fm-indication-modal-content {
background-color:
margin: 5% auto;
padding: 20px;
border: 1px solid
width: 35%;
border-radius: var(--fm-base-border-radius);
}
.fm-indication-modal .fm-indication-modal-content .fm-indication-modal-close {
color:
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.fm-indication-modal .fm-indication-modal-content .fm-indication-modal-content-body {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.fm-indication-component .fm-alert{
width: 80%;
display: block;
margin: 20px auto;
}
.fm-indication-modal-content-body .fm-rounded-icon{
padding: 10px 30px;
}
.fm-indication-modal-content-body svg{
width: 40px;
margin: 20px 0;
fill: var(--fm-primary-button-color);
}
.fm-indication-modal-content-body .title{
font-weight: bold;
margin :15px 0 0px 0;
}
@media (max-width: 700px) {
.fm-section-container.fm-indication-component .fm-indication-component-inner{
flex-direction: column;
}
.fm-section-container.fm-indication-component .fm-button-container{
width: 30%;
}
.fm-indication-component .indication-left-container{
padding: 20px;
}
.fm-indication-component .indication-card{
margin-left: 20px;
margin-right: 20px;
}
.fm-section-container.fm-indication-component .fm-indication-modal-content{
width: 85%;
}
.fm-indication-component .indication-card .fm-indication-models-btn .fm-flat-icon{
padding: 0;
}
.fm-indication-component .indication-card .fm-indication-models-btn-container{
flex-direction: column;
}
.fm-indication-component .indication-card .fm-indication-models-btn-container [fm-content]{
width: 100%;
}
}
`);
}