) => {\r\n this.setState({ isPopupOpen: true });\r\n };\r\n // Open popup by clicking on join now button\r\n private _renderPopUp = () => {\r\n return (\r\n \r\n );\r\n };\r\n\r\n // Render Popup title\r\n private _renderPopupTitle = () => {\r\n const { popUpHeading } = this.props.config;\r\n return (\r\n \r\n \r\n {popUpHeading && (\r\n \r\n )}\r\n \r\n );\r\n };\r\n // Render popup footer\r\n private _renderPopupFooter = () => {\r\n return <>>;\r\n };\r\n // Render popup body to show input fields\r\n private _renderPopupBody = () => {\r\n const subscribeResponse = this._getSubscribeResponse();\r\n const subscribeForm = this._renderForm();\r\n const { FormWrapper, FormContainer, nameInput, emailInput, checkboxPrivacyPolicy, subscribeButtton } = subscribeForm;\r\n return (\r\n \r\n {subscribeResponse}\r\n \r\n {nameInput}\r\n {emailInput}\r\n {checkboxPrivacyPolicy}\r\n {subscribeButtton}\r\n \r\n \r\n \r\n );\r\n };\r\n // Close popup and reset state\r\n private _closePopup = () => {\r\n this.setState({\r\n isPopupOpen: false,\r\n firstName: '',\r\n lastName: '',\r\n emailAddress: '',\r\n privacyPolicyChecked: false,\r\n firstNameError: false,\r\n lastNameError: false,\r\n emailError: false,\r\n requiredError: false,\r\n emailValidationError: false,\r\n privacyPolicyError: false,\r\n recaptchaError: false,\r\n responseReceived: false,\r\n responseError: false,\r\n reCaptchaChecked: false\r\n });\r\n };\r\n\r\n // Get all input fields and return as form fields\r\n private _renderForm(): ISubscribeNewsletterForm {\r\n return {\r\n FormWrapper: {\r\n className: 'newsletter-subscription',\r\n tag: 'div'\r\n },\r\n FormContainer: {\r\n className: 'newsletter-subscription-div',\r\n tag: 'div'\r\n },\r\n nameInput: this._renderFirstAndLastNameInput(),\r\n emailInput: this._renderEmailInput(),\r\n checkboxPrivacyPolicy: this._renderCheckboxPrivacyPolicy(),\r\n subscribeButtton: this._renderSubscribeButton()\r\n };\r\n }\r\n\r\n private _renderFirstAndLastNameInput(): React.ReactNode {\r\n return (\r\n \r\n
\r\n {this.state.firstNameError ? this._renderAlert('first-name-input') : ''}\r\n {this.state.lastNameError ? this._renderAlert('last-name-input') : ''}\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n );\r\n }\r\n\r\n private _renderEmailInput(): React.ReactNode {\r\n return (\r\n \r\n {this.state.emailError || this.state.emailValidationError ? this._renderAlert('email-address-input') : ''}\r\n \r\n
\r\n );\r\n }\r\n\r\n private _isEmailValid = (email: string): boolean => {\r\n const regex = /^(([^<>()\\[\\]\\\\.,;:\\s@']+(\\.[^<>()\\[\\]\\\\.,;:\\s@']+)*)|('.+'))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\r\n return regex.test(email);\r\n };\r\n\r\n private _renderCheckboxPrivacyPolicy(): React.ReactNode {\r\n return (\r\n \r\n {this.state.privacyPolicyError ? this._renderAlert('checkbox-privacy-policy') : ''}\r\n
\r\n
\r\n );\r\n }\r\n\r\n private _renderSubscribeButton(): React.ReactNode {\r\n return (\r\n \r\n \r\n
\r\n );\r\n }\r\n // Store input fields value to state\r\n private _handleChange = (name: string) => (e: React.ChangeEvent) => {\r\n const value = e.target.value;\r\n switch (name) {\r\n case 'firstName': {\r\n this.setState({\r\n firstName: value,\r\n firstNameError: false,\r\n requiredError: false,\r\n emailValidationError: false,\r\n privacyPolicyError: false\r\n });\r\n break;\r\n }\r\n case 'lastName': {\r\n this.setState({\r\n lastName: value,\r\n lastNameError: false,\r\n requiredError: false,\r\n emailValidationError: false,\r\n privacyPolicyError: false\r\n });\r\n break;\r\n }\r\n case 'emailAddress': {\r\n this.setState({\r\n emailAddress: value,\r\n emailError: false,\r\n requiredError: false,\r\n emailValidationError: false,\r\n privacyPolicyError: false\r\n });\r\n break;\r\n }\r\n case 'privacyPolicy': {\r\n const isChecked =\r\n this._PrivacyPolicyRef.current && this._PrivacyPolicyRef.current.checked\r\n ? this._PrivacyPolicyRef.current.checked\r\n : false;\r\n this.setState({\r\n privacyPolicyChecked: isChecked,\r\n requiredError: false,\r\n emailValidationError: false,\r\n privacyPolicyError: false\r\n });\r\n break;\r\n }\r\n default: {\r\n this.setState({ requiredError: false, emailValidationError: false, privacyPolicyError: false });\r\n }\r\n }\r\n };\r\n // Show error message on invalid email or if checkbox is not checked\r\n private _renderAlert(className: string): JSX.Element {\r\n const inputBoxErrors = this.state.firstNameError || this.state.lastNameError || this.state.emailError;\r\n if (inputBoxErrors) {\r\n this.requiredErrorMessage = this.props.resources.requiredTextErrorMessage;\r\n }\r\n if (this.state.emailAddress !== '' && this.state.emailValidationError) {\r\n this.emailValidationErrorMessage = this.props.resources.emailValidationErrorMessage;\r\n }\r\n if (!this.state.privacyPolicyChecked) {\r\n this.privacyPolicyErrorMessage = this.props.resources.privacyPolicyErrorMessage;\r\n }\r\n const requiredError = this.state.requiredError;\r\n const emailValidationError = this.state.emailValidationError;\r\n const privacyPolicyError = this.state.privacyPolicyError;\r\n return (\r\n <>\r\n {requiredError && (\r\n \r\n {this.requiredErrorMessage && (\r\n <>\r\n \r\n {this.requiredErrorMessage}\r\n >\r\n )}\r\n \r\n )}\r\n {emailValidationError && (\r\n \r\n {this.emailValidationErrorMessage && (\r\n <>\r\n \r\n {this.emailValidationErrorMessage}\r\n >\r\n )}\r\n \r\n )}\r\n {privacyPolicyError && (\r\n \r\n {this.privacyPolicyErrorMessage && (\r\n <>\r\n \r\n {this.privacyPolicyErrorMessage}\r\n >\r\n )}\r\n \r\n )}\r\n >\r\n );\r\n }\r\n\r\n // Get API response\r\n private _getSubscribeResponse(): React.ReactNode {\r\n return this.state.responseReceived && this.responseMessage ? (\r\n \r\n
\r\n {this.responseMessage}\r\n
\r\n
\r\n ) : null;\r\n }\r\n\r\n private _hasFirstNameValue = () => {\r\n return this._FirstNameInputRef && this._FirstNameInputRef.current && this._FirstNameInputRef.current.value ? true : false;\r\n };\r\n\r\n private _hasLastNameValue = () => {\r\n return this._LastNameInputRef && this._LastNameInputRef.current && this._LastNameInputRef.current.value ? true : false;\r\n };\r\n\r\n private _hasEmailAddressValue = () => {\r\n return this._EmailAddressInputRef && this._EmailAddressInputRef.current && this._EmailAddressInputRef.current.value ? true : false;\r\n };\r\n\r\n private _hasFormContainValues = () => {\r\n return this.hasFirstNameValue && this.hasLastNameValue && this.hasEmailAddressValue ? true : false;\r\n };\r\n\r\n private async _handleSubscribe(\r\n e: React.MouseEvent | React.KeyboardEvent | React.FormEvent\r\n ): Promise {\r\n this.hasFirstNameValue = this._hasFirstNameValue();\r\n this.hasLastNameValue = this._hasLastNameValue();\r\n this.hasEmailAddressValue = this._hasEmailAddressValue();\r\n const email = this.hasEmailAddressValue ? this._EmailAddressInputRef.current!.value : '';\r\n if (!this.hasFirstNameValue) {\r\n this.setState({\r\n firstNameError: true,\r\n requiredError: true\r\n });\r\n } else if (!this.hasLastNameValue) {\r\n this.setState({ lastNameError: true, requiredError: true });\r\n } else if (!this.hasEmailAddressValue) {\r\n this.setState({ emailError: true, requiredError: true });\r\n } else if (!this._isEmailValid(email)) {\r\n this.setState({ emailValidationError: true });\r\n } else if (!this._PrivacyPolicyRef.current!.checked) {\r\n this.setState({ privacyPolicyChecked: false, privacyPolicyError: true });\r\n } else {\r\n this.hasFormContainValues = this._hasFormContainValues();\r\n if (this.hasFormContainValues && this.state.privacyPolicyChecked && !this.state.emailValidationError) {\r\n try {\r\n // Make subscribe newsletter data-action call here with user data\r\n const contact = {\r\n email: this.state.emailAddress,\r\n emailType: 'Html',\r\n dataFields: [\r\n { key: 'FIRSTNAME', value: this.state.firstName },\r\n { key: 'LASTNAME', value: this.state.lastName }\r\n ],\r\n status: 'Subscribed'\r\n };\r\n const {\r\n context: { actionContext },\r\n config: { programID },\r\n resources: { programErrorMessage, programSuccessMessage }\r\n } = this.props;\r\n let isError = false;\r\n if (programID) {\r\n // call api here to create contact\r\n const response = await vSIInitiateRestCallAsync(\r\n { callerContext: actionContext },\r\n 'DotDigital',\r\n 'post',\r\n \"{'cache-control':'no-cache' , 'Accept':'application/json'}\",\r\n JSON.stringify(contact),\r\n '',\r\n `v2/contacts`\r\n );\r\n if (response.result) {\r\n const responseResult = JSON.parse(response.result);\r\n const errorMessage: IErrorMessage = responseResult;\r\n if (errorMessage.message && errorMessage.message.length > 0) {\r\n // Address book isn't found or any other issue So set error message\r\n isError = true;\r\n } else {\r\n // Contact created so now add contact in program\r\n // Get contact id\r\n const contactCreated: IContactCreatedResponse = responseResult;\r\n if (contactCreated.id) {\r\n // add this id in given programId\r\n const program: IPreferenceProgram = {\r\n contacts: [contactCreated.id],\r\n programId: programID\r\n };\r\n const programResponse = await vSIInitiateRestCallAsync(\r\n { callerContext: actionContext },\r\n 'DotDigital',\r\n 'post',\r\n \"{'cache-control':'no-cache' , 'Accept':'application/json'}\",\r\n JSON.stringify(program),\r\n '',\r\n `v2/programs/enrolments`\r\n );\r\n if (programResponse.result) {\r\n const programResponseResult = JSON.parse(programResponse.result);\r\n const error: IErrorMessage = programResponseResult;\r\n if (error.message && error.message.length > 0) {\r\n // Error in adding contact in Program\r\n // display error alert\r\n isError = true;\r\n } else {\r\n this.responseMessage = programSuccessMessage;\r\n // Contact has been added to address book\r\n this.setState({\r\n responseReceived: true,\r\n responseError: false,\r\n firstName: '',\r\n lastName: '',\r\n emailAddress: '',\r\n privacyPolicyChecked: false,\r\n requiredError: false,\r\n emailValidationError: false,\r\n recaptchaError: false\r\n });\r\n this._clearValues();\r\n }\r\n } else {\r\n isError = true;\r\n }\r\n } else {\r\n isError = true;\r\n }\r\n }\r\n }\r\n } else {\r\n // display error alert\r\n isError = true;\r\n }\r\n if (isError) {\r\n this.responseMessage = programErrorMessage;\r\n this.setState({ responseReceived: true, responseError: true });\r\n }\r\n } catch (e) {\r\n // @ts-ignore\r\n this.props.telemetry.error(e);\r\n this.responseMessage = this.props.resources.programErrorMessage;\r\n this.setState({ responseReceived: true, responseError: true });\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _clearValues(): void {\r\n if (this._PrivacyPolicyRef.current) {\r\n this._PrivacyPolicyRef.current.checked = false;\r\n }\r\n }\r\n}\r\n\r\nexport default DobbiesFooterNewsletter;\r\n","module.exports = React;","module.exports = ReactDOM;","\r\n // tslint:disable\r\n import * as EntityClasses from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\n import * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g'; \r\n \r\n \r\n /**\r\n * VSIRestAPIHandler entity interface.\r\n */\r\n export interface IVSIRestAPIHandler {\r\n Id: number;\r\n result?: string;\r\n ExtensionProperties?: Entities.CommerceProperty[];\r\n }\r\n \r\n /**\r\n * VSIRestAPIHandler entity class.\r\n */\r\n export class VSIRestAPIHandlerExtensionClass implements IVSIRestAPIHandler {\r\n \r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n public Id: number;\r\n \r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n public result: string;\r\n \r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n public ExtensionProperties: Entities.CommerceProperty[];\r\n \r\n // Navigation properties names\r\n \r\n /**\r\n * Construct an object from odata response.\r\n * @param {any} odataObject The odata result object.\r\n */\r\n constructor(odataObject?: any) {\r\n odataObject = odataObject || {};\r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n this.Id = odataObject.Id;\r\n \r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n this.result = odataObject.result;\r\n \r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n this.ExtensionProperties = undefined;\r\n if (odataObject.ExtensionProperties) {\r\n this.ExtensionProperties = [];\r\n for (var i = 0; i < odataObject.ExtensionProperties.length; i++) {\r\n if (odataObject.ExtensionProperties[i]) {\r\n if (odataObject.ExtensionProperties[i]['@odata.type']) {\r\n var className: string = odataObject.ExtensionProperties[i]['@odata.type'];\r\n className = className.substr(className.lastIndexOf('.') + 1).concat(\"Class\");\r\n if (EntityClasses[className]) {\r\n this.ExtensionProperties[i] = new EntityClasses[className](odataObject.ExtensionProperties[i])\r\n }\r\n } else {\r\n this.ExtensionProperties[i] = new EntityClasses.CommercePropertyClass(odataObject.ExtensionProperties[i]);\r\n }\r\n \r\n } else {\r\n // @ts-ignore - TODO bug fix #23427261 - remove ts-ignore - https://microsoft.visualstudio.com/DefaultCollection/OSGS/_workitems/edit/23427261/\r\n this.ExtensionProperties[i] = undefined;\r\n }\r\n }\r\n }\r\n \r\n }\r\n }\r\n","\r\n /*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n * THIS FILE IS AN AUTOGENERATED TYPESCRIPT PROXY EXTENSION.\r\n * TO USE THIS FILE, IT MUST BE ADDED TO A D365COMMERCE APPLICATION\r\n */\r\n // tslint:disable\r\n import { AsyncResult, callActionOrExecute, DataServiceQuery, IContext, IDataServiceRequest } from '@msdyn365-commerce/retail-proxy';\r\n // @ts-ignore\r\n import * as EntityClasses from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\n import * as DataServiceEntities from './DataServiceEntities.g';\r\n\r\n \r\n \r\n // @ts-ignore\r\n function vSIGetAPIResponseQuery(id?: number): DataServiceQuery {\r\n const key = (id) ? { Id: id } :null;\r\n return new DataServiceQuery(\"VSIGetRestAPIResponse\", \"VSIRestAPIHandler\", DataServiceEntities.VSIRestAPIHandlerExtensionClass, key);\r\n }\r\n\r\n \r\n export function createVSIInitiateRestCallInput(targetSystem: string, methodType: string, requestHeader: string, requestBody: string, urlParams: string, servicePath: string): IDataServiceRequest {\r\n const query = vSIGetAPIResponseQuery();\r\n return query.createDataServiceRequestForOperation('VSI_CallGenericRestAPIHandler', true, DataServiceEntities.VSIRestAPIHandlerExtensionClass, 'false', {bypassCache: 'get', returnEntity: 'DataServiceEntities.IVSIRestAPIHandler'}, {targetSystem: targetSystem, methodType: methodType, requestHeader: requestHeader, requestBody: requestBody, urlParams: urlParams, servicePath: servicePath });\r\n }\r\n\r\n \r\n export function vSIInitiateRestCallAsync(context: IContext, targetSystem: string, methodType: string, requestHeader: string, requestBody: string, urlParams: string, servicePath: string): AsyncResult {\r\n const request = createVSIInitiateRestCallInput(targetSystem, methodType, requestHeader, requestBody, urlParams, servicePath);\r\n return callActionOrExecute(request, context.callerContext);\r\n }\r\n ","const binding = { modules: {}, dataActions: {} };\n\n (binding.modules['dobbies-footer-newsletter'] = {\n c: () => require('partner/modules/dobbies-footer-newsletter/dobbies-footer-newsletter.tsx'),\n $type: 'contentModule',\n da: [],\n \n iNM: false,\n ns: '__local__',\n n: 'dobbies-footer-newsletter',\n p: '__local__',\n \n pdp: '',\n \n \n md: 'src/modules/dobbies-footer-newsletter'\n });\n \n\n \n window.__bindings__ = window.__bindings__ || {};\n window.__bindings__.modules = {\n ...window.__bindings__.modules || {},\n ...binding.modules\n };\n \n window.__bindings__.dataActions = {\n ...window.__bindings__.dataActions || {},\n ...binding.dataActions\n };\n export const viewDictionary = {};\n viewDictionary['__local__|__local__|modules|dobbies-footer-newsletter|dobbies-footer-newsletter'] = {\n c: () => require('partner/modules/dobbies-footer-newsletter/dobbies-footer-newsletter.view.tsx'),\n cn: '__local__-__local__-dobbies-footer-newsletter'\n };\nwindow.__bindings__ = window.__bindings__ || {};\nwindow.__bindings__.viewDictionary = {\n ...window.__bindings__.viewDictionary || {},\n ...viewDictionary\n };"],"sourceRoot":""}