Skip to content

Commit

Permalink
Merge pull request #465 from reportportal/develop
Browse files Browse the repository at this point in the history
Release Contact us form validation
  • Loading branch information
AmsterGet authored Jan 30, 2024
2 parents 3133eb5 + 6a32153 commit dfc6dc1
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 81 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ env:
AWS_S3_BUCKET_NAME : "rpp-landing"
AWS_REGION_NAME : "eu-central-1"
BUILD_DIR : "public/"
SALESFORCE_URL: https://test.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8
SALESFORCE_OID: 00D7a0000005481
SALESFORCE_MARKETING_AGREE_INPUT_NAME: 00N7T000000i00E
CONTACT_US_URL: https://testio--partial.sandbox.my.salesforce-sites.com/leadcapture/services/apexrest/leadservice
DOCUMENTATION_URL: http://rpp-docs.s3-website.eu-central-1.amazonaws.com
GTM_ID: GTM-MK7ZHTL
CLOUDFRONT_ID: EILUB1IE9EON0
Expand Down Expand Up @@ -64,9 +62,7 @@ jobs:
echo CONTENTFUL_ACCESS_TOKEN=${{ secrets.CONTENTFUL_ACCESS_TOKEN_DEV }} >> .env.production
echo CONTENTFUL_SPACE_ID=${{ secrets.CONTENTFUL_SPACE_ID_DEV }} >> .env.production
echo GTM_ID=${{ env.GTM_ID }} >> .env.production
echo SALESFORCE_URL=${{ env.SALESFORCE_URL }} >> .env.production
echo SALESFORCE_OID=${{ env.SALESFORCE_OID }} >> .env.production
echo SALESFORCE_MARKETING_AGREE_INPUT_NAME=${{ env.SALESFORCE_MARKETING_AGREE_INPUT_NAME }} >> .env.production
echo CONTACT_US_URL=${{ env.CONTACT_US_URL }} >> .env.production
echo DOCUMENTATION_URL=${{ env.DOCUMENTATION_URL }} >> .env.production
- name: Build the source code
Expand Down
10 changes: 2 additions & 8 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@

name: Deploy to prod (GitHub Pages)
env:
SALESFORCE_URL: https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8
SALESFORCE_OID: 00D24000000k2Rp
SALESFORCE_MARKETING_AGREE_INPUT_NAME: 00N7T000000i00E
CONTACT_US_URL: https://testio.my.salesforce-sites.com/leadcapture/services/apexrest/leadservice
DOCUMENTATION_URL: //reportportal.io/docs
DOCUMENTATION_BRANCH: https://github.com/reportportal/documentation/edit/master/
GTM_ID: GTM-MK7ZHTL
BUILD_DIR : "public/"

Expand Down Expand Up @@ -51,11 +48,8 @@ jobs:
echo CONTENTFUL_ACCESS_TOKEN=${{ secrets.CONTENTFUL_ACCESS_TOKEN }} >> .env.production
echo CONTENTFUL_SPACE_ID=${{ secrets.CONTENTFUL_SPACE_ID }} >> .env.production
echo GTM_ID=${{ env.GTM_ID }} >> .env.production
echo SALESFORCE_URL=${{ env.SALESFORCE_URL }} >> .env.production
echo SALESFORCE_OID=${{ env.SALESFORCE_OID }} >> .env.production
echo SALESFORCE_MARKETING_AGREE_INPUT_NAME=${{ env.SALESFORCE_MARKETING_AGREE_INPUT_NAME }} >> .env.production
echo CONTACT_US_URL=${{ env.CONTACT_US_URL }} >> .env.production
echo DOCUMENTATION_URL=${{ env.DOCUMENTATION_URL }} >> .env.production
echo DOCUMENTATION_BRANCH=${{ env.DOCUMENTATION_BRANCH }} >> .env.production
- name: Build the source code
run: npm run build
Expand Down
2 changes: 1 addition & 1 deletion src/components/ComparePlans/RowSection/RowSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface RowSectionProps {
}[];
}

const getBlocksWith = createBemBlockBuilder(['rowSection']);
const getBlocksWith = createBemBlockBuilder(['row-section']);

export const RowSection: FC<RowSectionProps> = ({ footer, footerButtons }) => {
const isDesktop = useMediaQuery({ query: $desktopSm });
Expand Down
4 changes: 0 additions & 4 deletions src/components/OfferPageWrapper/OfferPageWrapper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
@use 'src/styles/variables' as v;

.offer-page-wrapper {
.footer {
border: none;
}

&__pentagons {
display: flex;
flex-direction: column;
Expand Down
67 changes: 33 additions & 34 deletions src/containers/ContactUsPage/ContactUsForm/ContactUsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useEffect, useState } from 'react';
import React, { useState } from 'react';
import { FormikProvider, useFormik } from 'formik';
import { useBoolean } from 'ahooks';
import isEmpty from 'lodash/isEmpty';
import { Link } from '@app/components';
import { createBemBlockBuilder } from '@app/utils';

import { validate } from './utils';
import { validate, getBaseSalesForceValues } from './utils';
import { FormFieldWrapper } from './FormFieldWrapper';
import { FeedbackForm } from './FeedbackForm';
import { SalesForceFormBase } from './SalesForceFormBase';
import { FormInput } from './FormInput';
import { CustomCheckbox } from './CustomCheckbox';
import { MAX_LENGTH } from './constants';
Expand All @@ -20,39 +20,48 @@ const getBlocksWith = createBemBlockBuilder(['contact-us-form']);

export const ContactUsForm = ({ title, options, isDiscussFieldShown }) => {
const [isFeedbackFormVisible, { setTrue: showFeedbackForm }] = useBoolean(false);
const [iframe, setIframe] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const formik = useFormik({
initialValues: {
first_name: '',
last_name: '',
email: '',
company: '',
termsAgree: false,
wouldLikeToReceiveAds: false,
...(isDiscussFieldShown && { discuss: '' }),
},
validateOnBlur: false,
validateOnChange: false,
validate,
});
const { getFieldProps, validateForm, values } = formik;

const { dirty, isValid, getFieldProps } = formik;
const iframeName = 'dummyframe';
const handleSubmit = event => {
event.preventDefault();

useEffect(() => {
const dummyFrame = document.createElement('iframe');
validateForm().then(errors => {
if (isEmpty(errors)) {
setIsLoading(true);

dummyFrame.name = iframeName;
dummyFrame.id = iframeName;
dummyFrame.style.display = 'none';
const baseSalesForceValues = getBaseSalesForceValues(options);
const postData = {
...values,
...baseSalesForceValues,
};

document.body.appendChild(dummyFrame);

setIframe(dummyFrame);

return () => dummyFrame.parentNode.removeChild(dummyFrame);
}, []);

const handleSubmit = () => {
iframe.onload = () => showFeedbackForm();
iframe.onerror = () => showFeedbackForm();
fetch(process.env.CONTACT_US_URL, {
method: 'POST',
body: JSON.stringify(postData),
headers: {
'Content-Type': 'application/json',
},
}).finally(() => {
showFeedbackForm();
setIsLoading(false);
});
}
});
};

if (isFeedbackFormVisible) {
Expand All @@ -62,17 +71,7 @@ export const ContactUsForm = ({ title, options, isDiscussFieldShown }) => {
return (
<FormikProvider value={formik}>
<div className={getBlocksWith('-container')}>
<form
className={getBlocksWith()}
action={process.env.SALESFORCE_URL}
method="POST"
target={iframeName}
>
<SalesForceFormBase
additionalFields={options.map(option => (
<input key={option.name} type="hidden" {...option} />
))}
/>
<form className={getBlocksWith()}>
<FormInput name="first_name" label="First name" placeholder="John" maxLength={40} />
<FormInput name="last_name" label="Last name" placeholder="Smith" maxLength={80} />
<FormInput
Expand All @@ -92,7 +91,7 @@ export const ContactUsForm = ({ title, options, isDiscussFieldShown }) => {
maxLength={MAX_LENGTH}
/>
)}
<FormFieldWrapper name={process.env.SALESFORCE_MARKETING_AGREE_INPUT_NAME}>
<FormFieldWrapper name="wouldLikeToReceiveAds">
<CustomCheckbox label="Subscribe to ReportPortal news" />
</FormFieldWrapper>
<FormFieldWrapper name="termsAgree">
Expand All @@ -112,7 +111,7 @@ export const ContactUsForm = ({ title, options, isDiscussFieldShown }) => {
className="btn btn--primary btn--large"
type="submit"
data-gtm="send_request"
disabled={!(isValid && dirty && getFieldProps('termsAgree').value)}
disabled={!getFieldProps('termsAgree').value || isLoading}
onClick={handleSubmit}
>
Send request
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import React from 'react';
import classNames from 'classnames';
import omit from 'lodash/omit';

import './InputField.scss';

export const InputField = ({
className,
touched,
error,
value,
label,
initialValue,
initialTouched,
InputElement = 'input',
initialError,
...props
}) => (
<div
className={classNames('input-field', className, {
error: touched && error,
error,
filled: value,
})}
>
<label>
{label}
<InputElement className="input" value={value} {...props} />
<InputElement
className="input"
value={value}
{...omit(props, ['touched', 'initialValue', 'initialTouched', 'initialError'])}
/>
</label>
{touched && error ? <div className={classNames('error-message')}>{error}</div> : null}
{error ? <div className={classNames('error-message')}>{error}</div> : null}
</div>
);

This file was deleted.

This file was deleted.

15 changes: 15 additions & 0 deletions src/containers/ContactUsPage/ContactUsForm/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,18 @@ export const validate = values =>

return errors;
}, {});

export const getBaseSalesForceValues = options => {
const pageConfig = options.reduce(
(acc, { name, value }) => ({
...acc,
[name]: value,
}),
{},
);

return {
lead_status: 'New',
...pageConfig,
};
};
9 changes: 4 additions & 5 deletions src/styles/buttons.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@import 'variables';
@import 'mixins/font';
@import 'mixins/font-scale';
@use 'variables' as v;
@use 'mixins' as m;

a.btn--primary {
&:hover,
Expand All @@ -10,8 +9,8 @@ a.btn--primary {
}

.btn {
@include font-poppins($fw-semi-bold);
@include font-scale(base);
@include m.font-poppins(v.$fw-semi-bold);
@include m.font-scale(base);

display: flex;
align-items: center;
Expand Down
4 changes: 2 additions & 2 deletions src/styles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ html * {
}

body {
@include font-noto-sans();
@include font-scale();
@include m.font-noto-sans();
@include m.font-scale();

margin: 0;
background: var(--white);
Expand Down
12 changes: 9 additions & 3 deletions src/utils/contactUsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface BaseConfig {

type AvailableOption = { isYearly: boolean };

const SALESFORCE_SOURCE_NAME = 'ReportPortalSource__c';
const SALESFORCE_SOURCE_NAME = 'ReportPortalSource';
const LEAD_SOURCE = 'lead_source';
const packageNumbers = [25, 60, 160];
const yearlyOption = { isYearly: true };
Expand Down Expand Up @@ -341,8 +341,14 @@ export const createContactUsConfig = (pricingConfig: PricingConfigDto) => {
url: '/contact-us/general',
title: 'Contact us',
options: [
{ name: 'ReportPortalSource__c', value: 'Landing page / General' },
{ name: 'lead_source', value: 'RP General' },
{
name: SALESFORCE_SOURCE_NAME,
value: 'Landing page / General',
},
{
name: LEAD_SOURCE,
value: 'RP General',
},
],
info: `<p>Got questions or need information about ReportPortal?</p>
<ul>
Expand Down

0 comments on commit dfc6dc1

Please sign in to comment.