import classNames from 'classnames' import { fetchForms, Link, RichText, sendFormSubmission, Text, types, useAdminContext, useReactBricksContext, } from 'react-bricks/frontend' import { backgroundColorsEditProps, LayoutProps, sectionBordersEditProps, sectionDefaults, textGradientEditProps, } from '../../LayoutSideProps' import blockNames from '../../blockNames' import { gradients, textColors } from '../../colors' import Container from '../../shared/components/Container' import Section from '../../shared/components/Section' import { GoogleReCaptchaProvider, useGoogleReCaptcha, } from 'react-google-recaptcha-v3' import { useForm } from 'react-hook-form' import { createSubmissionError, FormSubmissionError, } from '../../shared/FormNewsletter/NewsletterUtils' export interface CallToActionProps extends LayoutProps { textGradient: keyof typeof gradients title: types.TextValue description: types.TextValue text: types.TextValue buttonText: types.TextValue privacy: types.TextValue formId: string } const NewsletterHeroForm: React.FC<{ buttonText: types.TextValue formId: string }> = ({ buttonText, formId }) => { const { executeRecaptcha } = useGoogleReCaptcha() const rbContext = useReactBricksContext() const { isAdmin } = useAdminContext() const { register, handleSubmit, formState: { errors, isSubmitting }, setError, } = useForm() const onSubmit = async ({ email, ...data }: any) => { try { if (!executeRecaptcha) { throw createSubmissionError( 'recaptchaUnavailable', 'reCAPTCHA is not available. Please reload the page and try again.' ) } let token: string | undefined try { token = await executeRecaptcha('form_submit') } catch (err) { console.log(err) throw createSubmissionError( 'recaptchaExecution', 'Failed to execute reCAPTCHA. Please try again.', err ) } if (!token) { throw createSubmissionError( 'recaptchaToken', 'Failed to verify reCAPTCHA token. Please try again.' ) } let result: Awaited> try { result = await sendFormSubmission({ appId: rbContext.appId, appEnv: rbContext.environment, token, formId, emailAddress: email, data, fetchOptions: { apiPrefix: rbContext.apiPrefix }, }) } catch (err) { throw createSubmissionError( 'submissionNetwork', 'We were unable to submit your form. Please check your connection and try again.', err ) } if (!result.success) { const message = 'There was a problem sending your request. Please try again.' throw createSubmissionError('submissionFailed', message) } } catch (err) { const fallbackMessage = 'There was a problem sending your request. Please try again.' const submissionError = err instanceof Error ? (err as FormSubmissionError) : createSubmissionError('submission', fallbackMessage, err) if ( !(err instanceof Error) && submissionError.originalError === undefined ) { submissionError.originalError = err } const message = submissionError.message || fallbackMessage const type = submissionError.submissionType || 'submission' if (setError) { setError(`root.${type}` as any, { type, message, }) } throw submissionError } } return (
{errors.root && (
    {Object.values(errors.root).map((err) => { if (typeof err !== 'object') { return (
  • {err}
  • ) } const { type, message } = err return (
  • {message}
  • ) })}
)}
) } const CallToAction: types.Brick = ({ backgroundColor, borderTop, borderBottom, paddingTop, paddingBottom, textGradient = gradients.NONE.value, title, description, text, buttonText, privacy, formId, }) => { const titleStyle = textGradient !== gradients.NONE.value ? { WebkitTextFillColor: 'transparent' } : {} const reCaptchaKey = process.env.NEXT_PUBLIC_RECAPTCHA_KEY || '' return (
(

{props.children}

)} placeholder="Call to action text" />
(

{props.children}

)} placeholder="Description" allowedFeatures={[types.RichTextFeatures.Bold]} />
( {props.children} )} placeholder="Call to action text" />
( {props.children} )} placeholder="Privacy..." allowedFeatures={[types.RichTextFeatures.Link]} renderLink={({ children, href, target, rel }) => ( {children} )} />
) } CallToAction.schema = { name: blockNames.NewsletterHero, label: 'Newsletter hero', category: 'call to action', tags: ['newsletter', 'subscribe', 'hero'], previewImageUrl: `/bricks-preview-images/${blockNames.NewsletterHero}.png`, playgroundLinkLabel: 'View source code on Github', playgroundLinkUrl: 'https://github.com/ReactBricks/reactbricks-starters/blob/main/packages/reactbricks-ui/nextjs-pages/src/cta/NewsletterHero/NewsletterHero.tsx', getDefaultProps: () => ({ ...sectionDefaults, paddingTop: '12', paddingBottom: '12', title: 'Stay in the loop with our newsletter!', textGradient: gradients.NONE.value, description: [ { type: 'paragraph', children: [ { text: 'Sent every ', }, { text: '2 weeks', bold: true, }, { text: ', no spam.', }, ], }, ], text: 'Join thousands of developers who want to change the way people edit website.', privacy: [ { type: 'paragraph', children: [ { text: 'By submitting the form you accept our ', }, { type: 'link', url: 'https://reactbricks.com/legal/privacy', children: [ { text: 'Privacy policy', }, ], }, ], }, ], buttonText: 'Subscribe', }), sideEditProps: [ { groupName: 'Form data', defaultOpen: true, props: [ { name: 'formId', label: 'Form', type: types.SideEditPropType.Select, selectOptions: { display: types.OptionsDisplay.Select, getOptions: async () => { const apiPrefix = useReactBricksContext().apiPrefix const items = await fetchForms({ apiPrefix }) return [ { value: '', label: '--Select Form--' }, ...items.map((item: any) => ({ value: item.id, label: item.name, })), ] }, }, }, ], }, { groupName: 'Title', defaultOpen: true, props: [textGradientEditProps], }, { groupName: 'Layout', defaultOpen: false, props: [backgroundColorsEditProps, ...sectionBordersEditProps], }, ], } export default CallToAction