Module: LeadFormHelper

Defined in:
app/helpers/lead_form_helper.rb

Overview

View helper: lead form.

Instance Method Summary collapse

Instance Method Details

Inline contact link that opens a modal instead of navigating away.
Use this to replace direct links like link_to 'contact us', cms_link('/contact') with
a modal experience that keeps users on the page.

This is a convenience wrapper around lazy_lead_form_modal with variant: :link

Examples:

Basic usage

Please <%= contact_link 'contact us' %> for more information.

With custom styling

<%= contact_link 'email us', class: 'fw-semibold' %>

With context

<%= contact_link 'get in touch', header_title: 'Questions about Snow Melting?' %>

Parameters:

  • text (String) (defaults to: 'contact us')

    Link text

  • options (Hash) (defaults to: {})

    Options hash

Options Hash (options):

  • :class (String)

    CSS classes for the link

  • :header_title (String)

    Modal header title

  • :header_intro (String)

    Modal header intro text

  • :show_upload (Boolean)

    Show file attachment option (default: true)

  • :application_type (String)

    Pre-select application type



165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/helpers/lead_form_helper.rb', line 165

def contact_link(text = 'contact us', options = {})
  lazy_lead_form_modal(
    variant: :link,
    button_text: text,
    link_class: options[:class],
    header_title: options[:header_title],
    header_intro: options[:header_intro],
    show_upload: options.fetch(:show_upload, true),
    application_type: options[:application_type],
    about_project: options[:about_project]
  )
end

#lazy_lead_form_modal(variant: :card, modal_id: nil, header_title: 'Contact Us', header_intro: "Have a question? We're here to help.", button_text: 'Send Message', button_icon: 'envelope', button_class: 'btn btn-primary btn-lg', link_class: nil, show_upload: true, business_focused: false, submit_label: 'Send Message', application_type: nil, about_project: nil) ⇒ Object

Lazy-loading modal contact form
The form content is loaded via Turbo Frame only when modal opens,
reducing page weight by deferring turnstile and uppy loading.

Examples:

Basic card

<%= lazy_lead_form_modal %>

Custom button

<%= lazy_lead_form_modal(
  variant: :button,
  header_title: 'Request a Quote',
  button_text: 'Get Quote',
  application_type: 'Floor Heating'
) %>

Parameters:

  • variant (:card, :button) (defaults to: :card)

    Display style (:card shows full CTA card, :button shows just trigger)

  • header_title (String) (defaults to: 'Contact Us')

    Modal header title

  • header_intro (String) (defaults to: "Have a question? We're here to help.")

    Subtext below title

  • button_text (String) (defaults to: 'Send Message')

    Button label text

  • button_icon (String) (defaults to: 'envelope')

    Font Awesome icon name

  • show_upload (Boolean) (defaults to: true)

    Show file attachment option in form

  • business_focused (Boolean) (defaults to: false)

    Show company fields expanded/first

  • application_type (String) (defaults to: nil)

    Pre-select application type (e.g., 'Floor Heating')

  • submit_label (String) (defaults to: 'Send Message')

    Form submit button text

  • modal_id (Object, nil) (defaults to: nil)
  • button_class (String) (defaults to: 'btn btn-primary btn-lg')
  • link_class (String, nil) (defaults to: nil)

    CSS classes for link variant

  • about_project (Object, nil) (defaults to: nil)


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'app/helpers/lead_form_helper.rb', line 206

def lazy_lead_form_modal(
  variant: :card,
  modal_id: nil,
  header_title: 'Contact Us',
  header_intro: "Have a question? We're here to help.",
  button_text: 'Send Message',
  button_icon: 'envelope',
  button_class: 'btn btn-primary btn-lg',
  link_class: nil,
  show_upload: true,
  business_focused: false,
  submit_label: 'Send Message',
  application_type: nil,
  about_project: nil
)
  render Www::LeadFormModalComponent.new(
    variant: variant,
    modal_id: modal_id,
    header_title: header_title,
    header_intro: header_intro,
    button_text: button_text,
    button_icon: button_icon,
    button_class: button_class,
    link_class: link_class,
    show_upload: show_upload,
    business_focused: business_focused,
    submit_label: submit_label,
    application_type: application_type,
    about_project: about_project
  )
end

#lead_form(submit_label: nil, lead_form_defaults: nil, show_fields: nil, lead_form_labels: {}, locale: I18n.locale, show_header: true, header_title: 'Contact Us', header_intro: %(Have a question? We're here to help.), layout: :vertical) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/helpers/lead_form_helper.rb', line 60

def lead_form(submit_label: nil,
              lead_form_defaults: nil,
              show_fields: nil,
              lead_form_labels: {},
              locale: I18n.locale,
              show_header: true,
              header_title: 'Contact Us',
              header_intro: %(Have a question? We're here to help.),
              layout: :vertical)
  submit_url = cms_link('/contact_es/send') if locale == :es

  I18n.with_locale(locale) do
    render partial: '/www/leads/lead_form', locals: {
                  show_fields:,
                  submit_label:,
                  lead_form_defaults:,
                  lead_form_labels:,
                  submit_url:,
                  show_header:,
                  header_title:,
                  header_intro:,
                  layout:
                }
  end
end

#lead_form_contact_locked?(party = @context_user) ⇒ Boolean

True when the current viewer is an established customer (past
guest/lead_qualify). Mirrors the server-side lock in
Lead#save_to_user: in that state the canonical contact data must not
be edited via lead forms — only via the account-profile flow. Inline
lead form partials swap their contact-input section for a read-only
"Submitting as" summary when this returns true.

Returns:

  • (Boolean)


11
12
13
14
# File 'app/helpers/lead_form_helper.rb', line 11

def lead_form_contact_locked?(party = @context_user)
  customer = party.respond_to?(:customer) ? party.customer : party
  customer && !customer.guest? && !customer.lead_qualify?
end

#lead_form_modal(modal_id: 'leadFormModal', button_text: 'Contact Us', button_class: 'btn btn-primary', button_icon: 'envelope', modal_title: nil, modal_intro: nil, show_upload: false, business_focused: false, submit_label: 'Send Message', lead_form_defaults: nil) ⇒ Object

Modal lead form with CTA button trigger
Usage: <%= lead_form_modal(button_text: "Tell us About your Project") %>



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/helpers/lead_form_helper.rb', line 115

def lead_form_modal(modal_id: 'leadFormModal', button_text: 'Contact Us', button_class: 'btn btn-primary', button_icon: 'envelope', modal_title: nil, modal_intro: nil, show_upload: false, business_focused: false, submit_label: 'Send Message',
                    lead_form_defaults: nil)
  render partial: '/www/leads/lead_form_modal', locals: {
    modal_id: modal_id,
    button_text: button_text,
    button_class: button_class,
    button_icon: button_icon,
    modal_title: modal_title || button_text,
    modal_intro: modal_intro,
    show_upload: show_upload,
    business_focused: business_focused,
    submit_label: submit_label,
    lead_form_defaults: lead_form_defaults
  }
end

#lead_form_pro_member?(party = @context_user) ⇒ Boolean

True when the current viewer's customer is already an established
Trade Pro or Dealer. Used by _lead_form_compact in its
business_focused (Trade Pro registration) variant to short-circuit
the form: an already-enrolled customer gets an "already enrolled"
panel with a link to /my_account instead of being asked to register
all over again.

Two gates, both required:

  1. Customer is past guest/lead_qualify — same lifecycle gate as
    lead_form_contact_locked?. Without this, a guest who picked a
    "TP - …" or "DL - …" company-type on a previous lead form
    (which assigns profile_id even pre-establishment, see
    Lead#save_to_user's guest/lead_qualify branch) would be wrongly
    classified as enrolled and never see the registration form.
  2. Customer's profile is Trade Pro or Dealer — backed by the
    canonical Customer#is_trade_pro? / Customer#is_dealer?
    predicates (which delegate to Profile#trade_pro? /
    Profile#dealer?, name-prefix convention — same shape as
    Profile#homeowner? / Customer#is_homeowner?).

Returns:

  • (Boolean)


35
36
37
38
39
40
41
42
# File 'app/helpers/lead_form_helper.rb', line 35

def lead_form_pro_member?(party = @context_user)
  customer = party.respond_to?(:customer) ? party.customer : party
  return false unless customer
  return false unless customer.respond_to?(:is_trade_pro?)
  return false if customer.guest? || customer.lead_qualify?

  customer.is_trade_pro? || customer.is_dealer?
end

#product_question_lead_form(presenter) ⇒ Object



131
132
133
134
135
136
137
138
139
140
# File 'app/helpers/lead_form_helper.rb', line 131

def product_question_lead_form(presenter)
  if presenter.is_a?(Www::ProductLinePresenter)
    product = nil
    product_line = presenter.slug_ltree.to_s
  elsif presenter.is_a?(Www::ProductCatalogPresenter)
    product = presenter.item.id
    product_line = nil
  end
  render partial: '/www/leads/product_question_lead_form', locals: { product_id: product, product_line: product_line }
end

#referral_program_lead_form(submit_label: nil, lead_form_defaults: nil, show_fields: nil, locale: I18n.locale) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/helpers/lead_form_helper.rb', line 100

def referral_program_lead_form(submit_label: nil, lead_form_defaults: nil, show_fields: nil, locale: I18n.locale)
  submit_url = cms_link('/contact_es/send') if locale == :es

  I18n.with_locale(locale) do
    render partial: '/www/leads/referral_program_lead_form', locals: {
                  show_fields: show_fields,
                  submit_label: submit_label,
                  lead_form_defaults: lead_form_defaults,
                  submit_url: submit_url
                }
  end
end

#setup_lead_form(lead_form_defaults = {}) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/helpers/lead_form_helper.rb', line 44

def setup_lead_form(lead_form_defaults = {})
  # Inline lead-form rendering needs per-user data (prefilled name/email/
  # phone via from_party). That's incompatible with Cloudflare edge
  # caching, so opt out the response automatically. Calling this from the
  # lazy-modal path (form_content) is a safe no-op since that endpoint
  # never sets edge-cache headers.
  controller.skip_edge_cache! if controller.respond_to?(:skip_edge_cache!)

  lead_form_defaults ||= {}
  lead_form_defaults[:preferred_locale] = I18n.locale.to_s
  task_type = lead_form_defaults.delete(:activity_type_task_type)
  lead_form_defaults[:activity_type_id] ||= ActivityType.find_by(task_type: task_type)&.id if task_type
  lead_form_defaults[:skip_activity] ||= false
  Lead.new(lead_form_defaults).from_party(@context_user)
end

#support_request_form(locale: I18n.locale, referred_sku: nil, referred_product_line: nil) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/helpers/lead_form_helper.rb', line 86

def support_request_form(locale: I18n.locale, referred_sku: nil, referred_product_line: nil)
  # if locale == :es
  #   submit_url = cms_link('/contact_es/send')
  # end
  I18n.with_locale(locale) do
    render partial: '/www/leads/support_request_form', locals: {
                  support_case_note: 'Incoming Support Request from Support page',
                  referred_sku: referred_sku,
                  referred_product_line: referred_product_line,
                  submit_url: cms_link('/contact/send')
                }
  end
end