fm-lp-factory
Version:
package created to build web ui components for FidelizarMais LP services
575 lines (505 loc) • 23.4 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
}
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 fm-indication-with-benefits-guide';
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("%componentGetIndicationCodeBtn%", componentTexts.getIndicationCodeBtn)
.replace("%whatsAppIcon%", whatsappFlat)
.replace("%whatsAppIconRounded%", whatsappRounded)
.replace("%emailIconRounded%", emailIconRounded)
.replace("%emailIcon%", emailIconFlat)
.replaceAll("%sendIndicationBtn%", componentTexts.sendIndicationBtn)
.replace("%listingTitle%", component.listing.title || "Benefícios incríveis");
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) {
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) {
window.open(`https://api.whatsapp.com/send/?phone=${input.value}&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) {
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-indication-component-inner">
<div class="indication-left-container">
<strong class="fm-h3">%title%</strong>
<p>%subtitle%</p>
<div class="fm-indication-component-inner-open-guide" fm-action="openGuideModal">
<span>VEJA MAIS BENEFÍCIOS INCRÍVEIS</span>
</div>
</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="closeIndicationModal">×</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="closeIndicationModal">×</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="text"
maxlength="18" 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>
<div class="fm-indication-component-guide-modal">
<div class="fm-indication-component-guide-modal-content">
<span class="fm-indication-component-guide-modal-close" fm-action="closeGuideModal">×</span>
<div class="fm-indication-component-guide-modal-content-body">
<div class="fm-indication-component-guide-modal-content-body-header">
<p class="fm-indication-component-guide-modal-content-body-title">%listingTitle%</p>
</div>
<div class="fm-indication-component-guide-modal-content-body-list-container">
<div class="fm-indication-component-guide-modal-content-body-list">
</div>
</div>
</div>
</div>
</div>
`;
const indicationGuideContent = /*html*/ `
<div class="fm-indication-component-guide-modal-content-body-list-content-item-header">
<span>%title%</span>
</div>
<div class="fm-indication-component-guide-modal-content-body-list-content-item-content">
</div>
`;
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='closeIndicationModal']").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='openGuideModal']").addEventListener("click", (event) => {
section.querySelector(".fm-indication-component-guide-modal").style.display = "block";
document.dispatchEvent(new CustomEvent("fm-open-indication-guide", {
detail: {
src: event.target
}
}));
});
section.querySelector("[fm-action='closeGuideModal']").addEventListener("click", (event) => {
const btn = event.target;
const modal = btn.closest(".fm-indication-component-guide-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]"));
});
if (component.listing) {
const guideContent = section.querySelector(".fm-indication-component-guide-modal-content-body-list");
component.listing.data.forEach((item) => {
const content = document.createElement("div");
content.className = "fm-indication-component-guide-modal-content-body-list-content-item";
content.innerHTML = indicationGuideContent
.replace("%title%", item.title);
item.data.forEach((subItem) => {
const subContent = document.createElement("div");
subContent.className = "fm-indication-component-guide-modal-content-body-list-content-item-content__item";
subContent.innerHTML = subItem;
content.querySelector(".fm-indication-component-guide-modal-content-body-list-content-item-content").appendChild(subContent);
});
guideContent.appendChild(content);
});
}
}
const css = () => {
updateFmTemplateCss( /*css*/ `
.fm-indication-component-inner {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
width: 100%;
}
.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, .fm-indication-component-guide-modal{
display: none;
position: fixed;
z-index: 10000;
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, .fm-indication-component-guide-modal .fm-indication-component-guide-modal-close{
color:
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.fm-indication-component-guide-modal .fm-indication-component-guide-modal-content{
background-color:
margin: 5% auto;
padding: 20px;
border: 1px solid
width: 70%;
border-radius: var(--fm-base-border-radius);
}
.fm-indication-component-guide-modal-content-body-list-container{
margin-top: 40px;
}
.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 screen and (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-inner-open-guide{
cursor: pointer;
border-radius: calc(var(--fm-base-border-radius) * 2);
border: 2px solid var(--fm-primary-button-color);
text-align: center;
padding: 10px 20px;
color: var(--fm-primary-button-color);
}
.fm-indication-component-guide-modal-content-body-list-content-item-header {
position: relative;
top: -35px;
background: var(--fm-card-primary-background);
border-radius: var(--fm-base-border-radius);
padding: 5px 10px;
left: -10px;
color: var(--fm-card-primary-text-color);
}
.fm-indication-component-guide-modal-content-body-list {
display: flex;
align-items: center;
gap: 30px;
flex-direction: row;
}
.fm-indication-component-guide-modal-content-body-list-content-item {
background: var(--fm-primary-color);
padding: 15px;
border-radius: var(--fm-base-border-radius);
width: 95%;
}
.fm-indication-component-guide-modal-content-body-list-content-item-content__item{
padding: 5px;
border-bottom: 1px dotted var(--fm-card-primary-background);
color: var(--fm-card-primary-text-color);
}
.fm-indication-component-guide-modal-content-body-list-content-item-content{
margin-top: -25px;
}
@media screen and (max-width: 700px) {
.fm-indication-component-guide-modal-content-body-list{
flex-direction: column;
}
.fm-indication-component-guide-modal .fm-indication-component-guide-modal-content{
width: 100%;
margin: 0 auto;
height: 100%;
}
.fm-indication-component-guide-modal{
padding-top: 0;
}
.fm-indication-component-guide-modal-content-body{
display: flex;
align-items: flex-start;
flex-direction: column;
align-content: center;
width: 100%;
height: 100%;
justify-content: center;
}
}
`);
}