diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1a962e443..6d873b81b 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -78,6 +78,12 @@ def set_form_variables @project.build_logo_image if @project.logo_image.blank? @project_statuses = ProjectStatus.all + @facilitators_array = Facilitator.joins(:user) + .order(:first_name, :last_name) + .map{|f| [f.name, f.user.id] } + @project.project_users = @project.project_users + .includes(:project) + .sort_by { |pu| pu.user.facilitator&.name.to_s.downcase } end def set_index_variables @@ -97,6 +103,18 @@ def project_params :inactive, :notes, :agency_type, :agency_type_other, :website_url, :project_status_id, :location_id, :windows_type_id, logo_image_attributes: [:id, :file, :_destroy], + sectorable_items_attributes: [ + :id, + :sector_id, + :_destroy, + ], + project_users_attributes: [ + :id, + :user_id, + :inactive, + :title, + :_destroy, + ], addresses_attributes: [ :id, :address_type, diff --git a/app/helpers/sector_helper.rb b/app/helpers/sector_helper.rb new file mode 100644 index 000000000..3c79931db --- /dev/null +++ b/app/helpers/sector_helper.rb @@ -0,0 +1,20 @@ +module SectorHelper + def sector_button(sector, font_size: "text-md") + link_to authenticated_root_path(sector), + class: "group inline-flex items-center gap-2 px-4 py-2 + border border-purple-800 text-purple-500 rounded-lg + hover:bg-purple-800 hover:text-white transition-colors duration-200 + #{font_size} shadow-sm leading-none whitespace-nowrap" do + + # --- Name: stays one line & turns white on hover --- + content_tag( + :span, + sector.name.to_s.truncate(30), + title: sector.name.to_s, + class: "font-semibold text-gray-900 whitespace-nowrap group-hover:text-white" + ) + end + end + + +end diff --git a/app/models/address.rb b/app/models/address.rb index 4006f6a25..d11db6187 100644 --- a/app/models/address.rb +++ b/app/models/address.rb @@ -11,6 +11,6 @@ class Address < ApplicationRecord scope :active, -> { where(inactive: false) } def name - "#{street}, #{city}, #{state} #{zip}" + "#{street_address}, #{city}, #{state} #{zip_code}" end end diff --git a/app/models/project.rb b/app/models/project.rb index 998081331..eb8dcbbab 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -22,6 +22,8 @@ class Project < ApplicationRecord # Nested attributes accepts_nested_attributes_for :logo_image, allow_destroy: true, reject_if: :all_blank accepts_nested_attributes_for :addresses, allow_destroy: true, reject_if: :all_blank + accepts_nested_attributes_for :sectorable_items, allow_destroy: true, reject_if: :all_blank + accepts_nested_attributes_for :project_users, allow_destroy: true, reject_if: :all_blank scope :active, -> { where(inactive: false) } diff --git a/app/views/projects/_address_fields.html.erb b/app/views/projects/_address_fields.html.erb index d84a9c407..afeed9f22 100644 --- a/app/views/projects/_address_fields.html.erb +++ b/app/views/projects/_address_fields.html.erb @@ -1,4 +1,9 @@ -
+
+
+ Address <%= "#" + (f.index.to_i + 1).to_s if f.object.persisted? %><%= ": " + f.object.name if f.object.persisted? %> +
+ +
@@ -122,5 +127,5 @@ <%= link_to_remove_association "✖ Remove", f, - class: "btn btn-danger-outline whitespace-nowrap" %> + class: "btn btn-danger-outline whitespace-nowrap" if f.object.persisted? %>
diff --git a/app/views/projects/_form.html.erb b/app/views/projects/_form.html.erb index 61dbb370a..c7114bb21 100644 --- a/app/views/projects/_form.html.erb +++ b/app/views/projects/_form.html.erb @@ -105,47 +105,80 @@ class: "rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" } %> - <%= f.input :project_status_id, - as: :select, - collection: @project_statuses, - include_blank: true, - label: "Status", - required: true, - input_html: { - class: "rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" - } %> + <% if current_user.super_user? %> +
+ <%= f.input :project_status_id, + as: :select, + collection: @project_statuses, + include_blank: true, + label: "Status", + required: true, + input_html: { + class: "rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200" + } %> +
+ <% else %> +
+ Project status: +
+ <%= f.object.project_status&.name %> + <% end %>
- <%= f.input :start_date, - label: "Affiliation start date", - as: :string, - input_html: { - type: 'date', - value: f.object.start_date&.strftime('%Y-%m-%d'), - class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" - } %> + <% if current_user.super_user? %> +
+ <%= f.input :start_date, + label: "Affiliation start date", + as: :string, + input_html: { + type: 'date', + value: f.object.start_date&.strftime('%Y-%m-%d'), + class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" + } %> +
+
+ <%= f.input :end_date, + label: "Affiliation end date", + as: :string, + input_html: { + type: 'date', + value: f.object.end_date&.strftime('%Y-%m-%d'), + class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" + } %> +
+ <% else %> +
+
+ Affiliation start date: +
+ <%= f.object.start_date&.strftime('%Y-%m-%d') %> +
- <%= f.input :end_date, - label: "Affiliation end date", - as: :string, - input_html: { - type: 'date', - value: f.object.end_date&.strftime('%Y-%m-%d'), - class: "block w-full rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" - } %> +
+
+ Affiliation end date: +
+ <%= f.object.end_date&.strftime('%Y-%m-%d') %> +
+ + <% end %> <%= f.input :website_url, label: "Website URL", as: :string, input_html: { class: "rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" } %> - <%= f.input :internal_id, - label: "Internal Project ID", - input_html: { - class: "rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" - } %> + <% if current_user.super_user? %> +
+ <%= f.input :internal_id, + label: "Internal Project ID", + input_html: { + class: "rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500" + } %> +
+ <% end %>
@@ -165,21 +198,25 @@ } %>
-
- <%= f.input :notes, - as: :text, - label: "Internal Notes", - input_html: { - rows: 3, - class: "rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-200" - } %> -
+ <% if current_user.super_user? %> +
+
+ <%= f.input :notes, + as: :text, + label: "Internal Notes", + input_html: { + rows: 3, + class: "rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-200" + } %> +
+
+ <% end %>
Addresses
-
+
<%= f.simple_fields_for :addresses do |sfi| %> <%= render "address_fields", f: sfi %> @@ -197,6 +234,37 @@
+
+
+ Facilitator affiliations +
+
+ <% if current_user.super_user? %> +
+ <%= f.fields_for :project_users do |project_user_form| %> + <%= render "project_user_fields", + f: project_user_form %> + <% end %> + +
+ <%= link_to_add_association "➕ Add Role", + f, + :project_users, + class: "btn btn-secondary-outline" %> +
+
+ <% else %> + <% f.object.user && f.object.user.project_users.each do |pu| %> +
+
  • <%= pu.title || pu.position %> - + <%= facilitator_profile_button(pu.user.facilitator) if pu.persisted? && pu.user.facilitator %> +
  • +
    + <% end %> + <% end %> +
    +
    +
    <% if @project.persisted? && current_user.super_user? %> diff --git a/app/views/projects/_project_user_fields.html.erb b/app/views/projects/_project_user_fields.html.erb new file mode 100644 index 000000000..424ed1913 --- /dev/null +++ b/app/views/projects/_project_user_fields.html.erb @@ -0,0 +1,44 @@ +<% if current_user.super_user? %> +
    + +
    + <%= f.input :user_id, + as: :select, + label: "Facilitator", + collection: @facilitators_array, + include_blank: true, + selected: f.object&.user_id, + input_html: { + class: "block w-full rounded-md border-gray-300 focus:ring-blue-500 focus:border-blue-500" + } %> +
    + +
    + <%= f.input :title, + as: :text, + input_html: { + rows: 1, + value: f.object&.title || f.object&.position, + } %> +
    + +
    +
    + <%= f.input :inactive, + as: :boolean, + label: "Inactive?", + wrapper_html: { class: "m-0 p-0" }, + label_html: { class: "text-sm font-medium text-gray-700 mb-0" }, + input_html: { class: "h-4 w-4 text-blue-600 border-gray-300 rounded" } %> +
    + + <%= link_to_remove_association "✖ Remove", + f, + class: "btn btn-danger-outline whitespace-nowrap" if f.object&.persisted? %> +
    +
    +<% else %> +
    +
  • <%= f.object.project&.name %> (<%= f.object.title || f.object.position %>)
  • +
    +<% end %> diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 343dd8fbe..840a82bcd 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -83,42 +83,39 @@
    - <% if true || @project.profile_show_facilitator? %> -
    -

    Windows facilitators

    - <% if @project.project_users.active.any? %> -
      - <% @project.project_users.active.each do |pu| %> -
    • - <%= link_to pu.user.facilitator.name, facilitator_path(pu.user.facilitator), - class: "text-blue-600 hover:underline font-medium" %> - <% if pu.position.present? %> - – <%= pu.title.presence || pu.position.humanize %> - <% end %> -
    • +
      +

      Windows facilitators

      + <% if @project.project_users.active.any? %> +
        + <% @project.project_users.active.each do |pu| %> +
      • + <%= pu.user.facilitator ? facilitator_profile_button(pu.user.facilitator) : pu.user.name %> + <% if pu.position.present? %> + – <%= pu.title.presence || pu.position.humanize %> + <% end %> +
      • + <% end %> +
      + <% else %> +

      No facilitators listed.

      + <% end %> +
      + + +
      +

      Sectors served

      +

      + <% if @project.sectorable_items.any? %> +

      + <% @project.sectorable_items.joins(:sector).order("sectors.name").map do |item| %> + <%= sector_button(item.sector) %> <% end %> -
    +
    <% else %> -

    No facilitators listed.

    + No sectors selected. <% end %> -
    - <% end %> - - - <% if true || @project.profile_show_sectors? %> -
    -

    Sectors served

    -

    - <% if @project.sectorable_items.any? %> - <%= @project.sectorable_items.joins(:sector).order("sectors.name").map do |item| %> - <% "#{item.sector.name}#{ " (Leader)" if item.is_leader? }" %> - <% end.join(", ") %> - <% else %> - No sectors selected. - <% end %> -

    -
    - <% end %> +

    +
    diff --git a/app/views/workshops/_show_tags.html.erb b/app/views/workshops/_show_tags.html.erb index 22250f877..32369a792 100644 --- a/app/views/workshops/_show_tags.html.erb +++ b/app/views/workshops/_show_tags.html.erb @@ -8,9 +8,7 @@
    <% workshop.sectors.order(:name).each do |sector| %> - - <%= sector.name %> - + <%= sector_button(sector, font_size: "text-xs") %> <% end %>