Class: Www::FaqListComponent

Inherits:
ApplicationComponent show all
Defined in:
app/components/www/faq_list_component.rb

Constant Summary collapse

DEFAULT_ICON =
'circle-question'
FILTER_TAG_LABELS =

Filter tag display configuration
Maps tag slugs to display labels and optional icons

{
  'trade-program' => { label: 'Trade Program', icon: 'handshake' },
  'trade-installation' => { label: 'Installation', icon: 'screwdriver-wrench' },
  'trade-testing' => { label: 'Testing & Troubleshooting', icon: 'gauge-high' },
  'trade-warranty' => { label: 'Warranty', icon: 'shield-check' }
}.freeze

Instance Method Summary collapse

Methods inherited from ApplicationComponent

#cms_link, #fetch_or_fallback, #image_asset_tag, #image_tag, #number_to_currency, #number_with_delimiter, #post_path, #post_url, #strip_tags

Constructor Details

#initialize(article_faqs:, section_title: nil, section_icon: nil, section_description: nil, initial_limit: 10, border: nil, filter_tags: nil, add_schema: true) ⇒ FaqListComponent

Enforce DB-backed FAQs only. Callers must pass an ActiveRecord::Relation or Array of Article records

Parameters:

  • article_faqs (ActiveRecord::Relation, Array<Article>)

    FAQ records to display

  • section_title (String, nil) (defaults to: nil)

    Optional title for the section

  • section_icon (String, nil) (defaults to: nil)

    Font Awesome icon name (defaults to 'circle-question')

  • section_description (String, nil) (defaults to: nil)

    Optional description for the section

  • initial_limit (Integer) (defaults to: 10)

    Number of FAQs to show initially (default: 10, use 0 to show all)

  • border (Symbol, nil) (defaults to: nil)

    Border style: :top, :bottom, or :both

  • filter_tags (Array<String>, nil) (defaults to: nil)

    Optional list of tags to enable filtering (displayed as clickable badges)



23
24
25
26
27
28
29
30
31
32
33
# File 'app/components/www/faq_list_component.rb', line 23

def initialize(article_faqs:, section_title: nil, section_icon: nil, section_description: nil, initial_limit: 10, border: nil, filter_tags: nil, add_schema: true)
  super()
  @article_faqs = Array(article_faqs).compact
  @section_title = section_title
  @section_icon = section_icon || DEFAULT_ICON
  @section_description = section_description
  @initial_limit = initial_limit
  @border = border
  @filter_tags = filter_tags
  @add_schema = add_schema
end

Instance Method Details

#before_renderObject

Raises:

  • (ArgumentError)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/components/www/faq_list_component.rb', line 40

def before_render
  super
  return unless @article_faqs.present?

  @article_faqs = dedupe_faqs_by_subject(@article_faqs)

  # Guard: ensure we received Article-like objects (DB-backed), not raw hashes
  raise ArgumentError, 'FaqListComponent expects DB-backed Article FAQ records; raw hashes are no longer supported' unless @article_faqs.first.respond_to?(:subject) && @article_faqs.first.respond_to?(:solution)

  # Limit JSON-LD schema to the initially-visible FAQs.
  # Hidden FAQs are lazy-loaded via Turbo Frame and their content is not
  # rendered server-side, so including them in schema would call
  # localized_solution for every FAQ (Liquid + Nokogiri per item) while
  # Google only surfaces a handful of FAQ rich results anyway.
  schema_faqs = @initial_limit.positive? ? @article_faqs.first(@initial_limit) : @article_faqs
  helpers.add_page_schema(:faq, schema_faqs) if @add_schema
end

#render?Boolean

Skip rendering entirely if there are no FAQs - this is the idiomatic ViewComponent approach

Returns:

  • (Boolean)


36
37
38
# File 'app/components/www/faq_list_component.rb', line 36

def render?
  @article_faqs.present?
end