Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions app/controllers/facilitators_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def index
facilitators = Facilitator
.searchable
.search_by_params(params.to_unsafe_h)
.joins(:user)
.includes(:user).references(:user)
.order(:first_name, :last_name)
@facilitators_count = facilitators.size
@facilitators = facilitators.paginate(page: params[:page], per_page: per_page)
Expand Down Expand Up @@ -80,6 +80,7 @@ def set_form_variables
end
end
@facilitator.build_user if @facilitator.user.blank? # Build a fresh one if missing
@facilitator.build_avatar_image if @facilitator.avatar_image.blank?

@facilitator.user.project_users.first || @facilitator.user.project_users.build
projects = if current_user.super_user?
Expand All @@ -93,9 +94,13 @@ def set_form_variables
# Only allow a list of trusted parameters through.
def facilitator_params
params.require(:facilitator).permit(
:first_name, :last_name, :primary_email_address, :primary_email_address_type,
:first_name, :last_name,
:primary_email_address, :primary_email_address_type,
:street_address, :city, :state, :zip, :country, :mailing_address_type,
:phone_number, :phone_number_type,:bio, :created_by_id, :updated_by_id,
:phone_number, :phone_number_type,
:created_by_id, :updated_by_id,
:bio,
:display_name_preference,
:pronouns,
:profile_show_name_preference,
:profile_is_searchable,
Expand Down Expand Up @@ -142,7 +147,14 @@ def facilitator_params
:state2,
:zip2,
:notes,
project_users_attributes: [:id, :project_id, :position, :inactive, :_destroy]
project_users_attributes: [
:id,
:project_id,
:position,
:title,
:inactive,
:_destroy
]
],
)
end
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ def set_user
end

def set_form_variables
@facilitator = @user.facilitator ||
Facilitator.where(id: params[:facilitator_id]).first if params[:facilitator_id].present?
@user.project_users.first || @user.project_users.build
projects = if current_user.super_user?
Project.active
Expand All @@ -139,7 +141,7 @@ def user_params
:agency_id, :facilitator_id, :created_by_id, :updated_by_id,
:confirmed, :inactive, :super_user, :legacy, :legacy_id,
avatar_image_attributes: [:id, :file, :_destroy],
project_users_attributes: [:id, :project_id, :position, :inactive, :_destroy]
project_users_attributes: [:id, :project_id, :position, :title, :inactive, :_destroy]
)
end
end
10 changes: 10 additions & 0 deletions app/decorators/event_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ def times(display_day: false, display_date: false)
line
end

def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("workshop_default_hands.png")
end
end

def breadcrumbs
"#{bookmarks_link} >> #{bookmarkable_link}".html_safe
end
Expand Down
4 changes: 4 additions & 0 deletions app/decorators/event_registration_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ def title

def description
end

def main_image_url
event.decorate.main_image_url
end
end
2 changes: 1 addition & 1 deletion app/decorators/facilitator_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def badges
badges << ["Legacy Facilitator (10+ years)", "yellow"] if years >= 10
badges << ["Seasoned Facilitator (3-10 years)", "gray"] if member_since.present? && years >= 3
badges << ["New Facilitator (<3 years)", "green"] if member_since.present? && years < 3
badges << ["Spotlighted Facilitator", "gray"] if true || stories_as_spotlighted_facilitator
badges << ["Spotlighted Facilitator", "gray"] if stories_as_spotlighted_facilitator
badges << ["Events Attended", "blue"] if user.events.any?
badges << ["Workshop Author", "indigo"] if user.workshops.any? # indigo
badges << ["Story Author", "rose"] if user.stories_as_creator.any? # pink
Expand Down
11 changes: 11 additions & 0 deletions app/decorators/resource_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ def featured_url
url.empty? ? h.resource_path(resource) : url
end


def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("theme_default.png")
end
end

def truncated_author
h.truncate author, length: 20
end
Expand Down
10 changes: 10 additions & 0 deletions app/decorators/story_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,14 @@ def inactive?
def workshop_title
workshop&.title || external_workshop_title
end

def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("theme_default.png")
end
end
end
10 changes: 10 additions & 0 deletions app/decorators/story_idea_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ def title
def description
body.truncate(100)
end

def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("theme_default.png")
end
end
end
10 changes: 10 additions & 0 deletions app/decorators/workshop_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ def sector_has_name?(form)
form.object.name
end

def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("workshop_default.jpg")
end
end

def breadcrumbs
if title
"#{breadcrumbs_title} >> #{breadcrumb_link} >> Workshop Log".html_safe
Expand Down
17 changes: 9 additions & 8 deletions app/decorators/workshop_idea_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
class WorkshopIdeaDecorator < Draper::Decorator
delegate_all

# Define presentation-specific methods here. Helpers are accessed through
# `helpers` (aka `h`). You can override attributes, for example:
#
# def created_at
# helpers.content_tag :span, class: 'time' do
# object.created_at.strftime("%a %m/%d/%y")
# end
# end
def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("workshop_default.jpg")
end
end

def display_spanish_fields
[
Expand Down
13 changes: 13 additions & 0 deletions app/decorators/workshop_log_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class WorkshopLogDecorator < Draper::Decorator
delegate_all

def main_image_url
if main_image&.file&.attached?
Rails.application.routes.url_helpers.url_for(main_image.file)
elsif gallery_images.first&.file&.attached?
Rails.application.routes.url_helpers.url_for(gallery_images.first.file)
else
ActionController::Base.helpers.asset_path("workshop_default.jpg")
end
end
end
4 changes: 4 additions & 0 deletions app/decorators/workshop_variation_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def display_code
end
end

def main_image_url
workshop.decorate.main_image_url
end

private

def method_name
Expand Down
87 changes: 44 additions & 43 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,53 +130,54 @@ def sortable_field_display_name(name)
end
end

def title_with_badges(record, admin: false, display_windows_type: false)
content_tag :div, class: "flex flex-col" do

# ---- BADGE ROW ---------------------------------------------------------
badge_row = content_tag :div, class: "flex flex-wrap items-center gap-2 mb-1" do
fragments = []

# Hidden badge
if admin && record.respond_to?(:inactive?) &&
record.inactive? && controller_name != "dashboard"
fragments << content_tag(
:span,
content_tag(:i, "", class: "fa-solid fa-eye-slash mr-1") + " Hidden",
class: "inline-flex items-center px-2 py-0.5 rounded-full
text-sm font-medium bg-blue-100 text-gray-600 whitespace-nowrap"
)
end

# Featured badge
if record.respond_to?(:featured?) &&
record.featured? && controller_name != "dashboard"
fragments << content_tag(
:span,
"🌟 Featured",
class: "inline-flex items-center px-2 py-0.5 rounded-full
text-sm font-medium bg-yellow-100 text-yellow-800 whitespace-nowrap"
)
end

safe_join(fragments)
end

# ---- TITLE + WINDOWS TYPE ------------------------------------------------
title_content = record.title.to_s

if display_windows_type && record.respond_to?(:windows_type) && record.windows_type.present?
title_content += " (#{record.windows_type.short_name})"
end
def title_with_badges(record, font_size: "text-lg", record_title: nil,
show_hidden_badge: false, display_windows_type: false)
fragments = []

# --- Hidden badge ---
if show_hidden_badge && record.respond_to?(:inactive?) &&
record.inactive? && controller_name != "dashboard"
fragments << content_tag(
:span,
content_tag(:i, "", class: "fa-solid fa-eye-slash mr-1") + " Hidden",
class: "inline-flex items-center px-2 py-0.5 rounded-full
text-sm font-medium bg-blue-100 text-gray-600 whitespace-nowrap"
)
end

title_row = content_tag(
# --- Featured badge ---
if record.respond_to?(:featured?) && record.featured? && controller_name != "dashboard"
fragments << content_tag(
:span,
title_content.html_safe,
class: "text-lg font-semibold text-gray-900 leading-tight"
"🌟 Dashboard Feature",
class: "inline-flex items-center px-2 py-0.5 rounded-full
text-sm font-medium bg-yellow-100 text-yellow-800 whitespace-nowrap"
)
end

title_content = record_title.presence || record.title.to_s

if display_windows_type && record.respond_to?(:windows_type) && record.windows_type.present?
title_content += " (#{record.windows_type.short_name})"
end

# Combine badge row + title row
safe_join([badge_row, title_row])
title_row = content_tag(
:span,
title_content.html_safe,
class: "#{font_size} font-semibold text-gray-900 leading-tight"
)

# ---- Combine rows intelligently ----
if fragments.any?
content_tag :div, class: "flex flex-col" do
safe_join([
content_tag(:div, safe_join(fragments), class: "flex flex-wrap items-center gap-2 mb-1"),
title_row
])
end
else
# No badges: just return the title with no empty div wrapper
title_row
end
end

Expand Down
27 changes: 27 additions & 0 deletions app/helpers/facilitator_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module FacilitatorHelper

def facilitator_profile_button(facilitator, size: 10)
link_to facilitator_path(facilitator),
class: "btn btn-secondary-outline flex items-center gap-3 px-4 py-2 rounded-lg" do

facilitator = facilitator.decorate
avatar = if facilitator.avatar_image.present?
image_tag url_for(facilitator.avatar_image.file),
class: "w-10 h-10 rounded-full object-cover border border-gray-300 shadow-sm"
else
image_tag "missing.png",
class: "w-10 h-10 rounded-full object-cover border border-dashed border-gray-300"
end

name = content_tag(:span, facilitator.name, class: "font-semibold text-gray-900")

pronouns = if facilitator.pronouns_display.present?
content_tag(:span, facilitator.pronouns_display,
class: "text-xs text-gray-500 italic")
end

avatar + content_tag(:div, name + (pronouns || "").html_safe,
class: "flex flex-col leading-tight text-left")
end
end
end
15 changes: 9 additions & 6 deletions app/models/facilitator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class Facilitator < ApplicationRecord
has_many :sectors, through: :sectorable_items
has_many :stories_as_spotlighted_facilitator, inverse_of: :spotlighted_facilitator, class_name: "Story",
dependent: :restrict_with_error
# has_many through
has_many :event_registrations, through: :user

# Image associations
has_one :avatar_image, -> { where(type: "Images::SquareImage") },
as: :owner, class_name: "Images::SquareImage",
Expand Down Expand Up @@ -68,19 +71,19 @@ def sector_list
def name
case display_name_preference
when "full_name"
user.full_name
full_name
when "first_name_last_initial"
"#{user.first_name} #{user.last_name.first}"
"#{first_name} #{last_name.first}"
when "first_name_only"
user.first_name
first_name
when "last_name_only"
user.last_name
last_name
else
user.full_name
full_name
end
end

def full_name
user.full_name
"#{first_name} #{last_name}"
end
end
Loading