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
9 changes: 6 additions & 3 deletions app/views/events/recipients.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@
the avatar stays blank). Calm palette: neutral name/org links, with
the sector chips as the single accent. %>
<% dp = person.decorate %>
<% has_sectors = person.sectors.any? %>
<%# Primary service area first (rendered as a darker-green crowned chip),
then the additional sectors alphabetically. %>
<% sectorable_items = person.sectorable_items_primary_first %>
<% has_sectors = sectorable_items.any? %>
<div class="relative px-5 py-4 pr-12 <%= DomainTheme.bg_class_for(:scholarships, intensity: 100) %> border-b <%= DomainTheme.border_class_for(:scholarships) %>">
<button type="button" data-action="expandable-card#toggle"
aria-label="Toggle <%= person.name %> application"
Expand Down Expand Up @@ -119,8 +122,8 @@
<% if has_sectors %>
<div class="flex flex-wrap items-center gap-2">
<span class="text-xs font-semibold uppercase tracking-wide text-gray-400">Serves</span>
<% person.sectors.sort_by(&:name).each do |sector| %>
<%= render "sectors/tagging_label", sector: sector %>
<% sectorable_items.each do |si| %>
<%= render "sectors/tagging_label", sector: si.sector, is_primary: si.is_primary? %>
<% end %>
</div>
<% elsif service_area_text.present? %>
Expand Down
14 changes: 8 additions & 6 deletions app/views/events/staff.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
<% active_affiliation = person.affiliations.find { |a| !a.inactive? } %>
<% org = active_affiliation&.organization %>
<% bio = event_staff.public_bio %>
<% sectors = person.profile_show_sectors? ? person.sectors.sort_by(&:name) : [] %>
<%# Primary sector first (starred, darker chip), then the rest alphabetically —
the same treatment as the recipients page. %>
<% sector_items = person.profile_show_sectors? ? person.sectorable_items.includes(:sector).sort_by { |si| [ si.is_primary? ? 0 : 1, si.sector&.name.to_s.downcase ] } : [] %>
<%# Facilitator tenure → one experience badge, computed from already-loaded
affiliations (avoids the decorator's query-heavy badges call). Thresholds
match PersonDecorator#compute_badges. %>
Expand Down Expand Up @@ -93,13 +95,13 @@
</span>
<% end %>

<% if sectors.any? %>
<% if sector_items.any? %>
<div class="mt-1.5 flex flex-wrap justify-center gap-1">
<% sectors.first(3).each do |sector| %>
<span class="px-2 py-0.5 rounded-md text-xs font-medium <%= DomainTheme.bg_class_for(:sectors, intensity: 100) %> <%= DomainTheme.text_class_for(:sectors, intensity: 700) %>"><%= sector.name %></span>
<% sector_items.first(3).each do |si| %>
<%= render "sectors/tagging_label", sector: si.sector, is_primary: si.is_primary? %>
<% end %>
<% if sectors.size > 3 %>
<span class="px-2 py-0.5 rounded-md text-xs font-medium text-gray-400">+<%= sectors.size - 3 %></span>
<% if sector_items.size > 3 %>
<span class="px-2 py-0.5 rounded-md text-xs font-medium text-gray-400">+<%= sector_items.size - 3 %></span>
<% end %>
</div>
<% end %>
Expand Down
5 changes: 4 additions & 1 deletion app/views/people/people_results.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@
</td>
<!-- Sectors -->
<td class="px-4 py-2 text-sm text-gray-800">
<% sectors = person.sectorable_items.to_a %>
<%# Index stays scannable: show only the primary sector(s) as the
darker-green starred chip; the full set lives on the profile. %>
<% sectors = person.sectorable_items.select(&:is_primary?).sort_by { |si| si.sector&.name.to_s.downcase } %>
<% if sectors.any? %>
<div class="flex flex-wrap gap-2">
<% sectors.each do |si| %>
<%= render "sectors/tagging_label",
sector: si.sector,
is_primary: true,
display_leader: true,
is_leader: si.is_leader %>
<% end %>
Expand Down
51 changes: 17 additions & 34 deletions app/views/people/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -124,44 +124,27 @@
<% end %>
<!-- Sectors -->
<% if @person.profile_show_sectors? %>
<% sectorable_items = @person.sectorable_items.includes(:sector).order("sectors.name") %>
<% primary_sector_items = sectorable_items.select(&:is_primary?) %>
<% additional_sector_items = sectorable_items.reject(&:is_primary?) %>
<%# One combined list: the primary sector leads as a darker-green starred
chip, followed by the additional sectors alphabetically and any
free-text "Other" responses. %>
<% sectorable_items = @person.sectorable_items.includes(:sector).sort_by { |si| [ si.is_primary? ? 0 : 1, si.sector&.name.to_s.downcase ] } %>
<% other_service_areas = @person.other_service_area_responses %>
<div class="md:col-span-2 p-3">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<h2 class="text-lg font-semibold text-gray-800 mb-3">Primary sector</h2>
<% if primary_sector_items.any? %>
<div class="flex flex-wrap gap-2">
<% primary_sector_items.each do |si| %>
<%= render "sectors/tagging_label",
sector: si.sector,
display_leader: true,
is_leader: si.is_leader %>
<% end %>
</div>
<% else %>
<p class="text-gray-500 italic">None selected.</p>
<h2 class="text-lg font-semibold text-gray-800 mb-3">Sectors</h2>
<% if sectorable_items.any? || other_service_areas.any? %>
<div class="flex flex-wrap gap-2">
<% sectorable_items.each do |si| %>
<%= render "sectors/tagging_label",
sector: si.sector,
is_primary: si.is_primary?,
display_leader: true,
is_leader: si.is_leader %>
<% end %>
<%= render "people/other_responses", responses: other_service_areas %>
</div>
<div>
<h2 class="text-lg font-semibold text-gray-800 mb-3">Additional sectors</h2>
<% if additional_sector_items.any? || other_service_areas.any? %>
<div class="flex flex-wrap gap-2">
<% additional_sector_items.each do |si| %>
<%= render "sectors/tagging_label",
sector: si.sector,
display_leader: true,
is_leader: si.is_leader %>
<% end %>
<%= render "people/other_responses", responses: other_service_areas %>
</div>
<% else %>
<p class="text-gray-500 italic">None selected.</p>
<% end %>
</div>
</div>
<% else %>
<p class="text-gray-500 italic">None selected.</p>
<% end %>
</div>
<% end %>
</div>
Expand Down
15 changes: 11 additions & 4 deletions app/views/sectors/_tagging_label.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@

<% display_leader ||= false %>

<% bg_color ||= DomainTheme.bg_class_for(:sectors) %>
<% is_primary ||= false %>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: is_primary defaults to false, so the ~10 existing callers of this partial render unchanged; only the recipients page opts in.


<%# Primary service areas read as a darker-green chip with a star so they stand
out from the additional sectors, matching the star used in the chip editor;
everyone else keeps the light-lime default. %>
<% bg_color ||= is_primary ? "bg-lime-200" : DomainTheme.bg_class_for(:sectors) %>

<%# bg_hover_color ||= DomainTheme.bg_class_for(:sectors, hover: true) %>

<% bg_hover_color ||= "bg-lime-200" %>
<% bg_hover_color ||= is_primary ? "bg-lime-300" : "bg-lime-200" %>

<% text_color ||= is_primary ? "text-lime-800" : "text-gray-500" %>

<% if sector %>
<%= link_to taggings_path(sector_names_all: sector.name),
Expand All @@ -17,11 +24,11 @@
rounded-md
border #{ DomainTheme.border_class_for(:sectors) } hover:#{ DomainTheme.border_class_for(:sectors, intensity: 500) }
#{ bg_color } hover:#{ bg_hover_color }
text-gray-500
#{ text_color }
px-3 py-1
text-sm font-medium
transition" do %>
<span data-tag-link-loading-target="text"><%= sector.name %><% if display_leader && is_leader %><span class="ml-1 text-xs text-indigo-600">(Leader)</span><% end %></span>
<span data-tag-link-loading-target="text"><% if is_primary %><i class="fa-solid fa-star mr-1 text-xs text-amber-400" aria-hidden="true" title="Primary service area"></i><% end %><%= sector.name %><% if display_leader && is_leader %><span class="ml-1 text-xs text-indigo-600">(Leader)</span><% end %></span>
<span data-tag-link-loading-target="spinner" class="hidden"><i class="fa-solid fa-spinner animate-spin" aria-hidden="true"></i></span>
<% end %>
<% end %>
9 changes: 9 additions & 0 deletions db/seeds/dev/events_management.rb
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,15 @@
end
# Service area chart reads SectorableItem tags, mirroring assign_tags.
sectors.each { |sector| SectorableItem.find_or_create_by!(sector: sector, sectorable: person) }
# Make the first submitted service area the person's single primary sector, so the
# recipients page + profile crown a primary that matches what they selected on the
# registration form. Demote any other primary first to keep exactly one (a person
# registered for several events is enriched once per event). Idempotent.
primary_sector = sectors.first
if primary_sector

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 From Claude: Demoting any other primary before setting this one keeps exactly one primary even when a person is enriched once per event they registered for — otherwise a multi-event registrant could end up with two starred sectors.

person.sectorable_items.where(is_primary: true).where.not(sector: primary_sector).update_all(is_primary: false)
person.sectorable_items.find_by(sector: primary_sector)&.update!(is_primary: true)
end
end

# Give the flagship cohort registration submissions so its Background charts have
Expand Down
9 changes: 5 additions & 4 deletions spec/requests/people_other_responses_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ def answer(identifier, value)
before { sign_in admin }

describe "profile page" do
it "shows the Other service area as an additional sector" do
it "shows the Other service area as a free-text chip, not the primary sector" do
person.update!(profile_show_sectors: true)
answer("primary_service_area", "Other: Equine therapy")

get person_path(person)

expect(response.body).to include("Equine therapy")
# The Other chip sits in the "Additional sectors" column, not "Primary sector".
additional_section = response.body.split("Additional sectors").last
expect(additional_section).to include("Equine therapy")
# The combined Sectors list renders it via the free-text "(other)" chip rather
# than promoting it to the starred primary sector.
equine_chip = response.body[/Equine therapy.{0,80}/m]
expect(equine_chip).to include("(other)")
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/requests/people_profile_flags_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
profile_show_member_since: "Facilitator since",
profile_show_phone: "555-123-4567",
profile_show_affiliations: "Affiliations",
profile_show_sectors: "mb-3\">Primary sector</h2>",
profile_show_sectors: "mb-3\">Sectors</h2>",
profile_show_bio: "mb-3\">Bio</h2>",
profile_show_workshops: "mb-3\">Workshops authored</h2>",
profile_show_workshop_variations: "Workshop variations authored",
Expand Down
14 changes: 14 additions & 0 deletions spec/views/sectors/_tagging_label.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,18 @@
expect(rendered).to include("Survivors")
expect(rendered).to include("sector_names_all=Survivors")
end

it "renders a plain lime chip without a star by default" do
render partial: "sectors/tagging_label", locals: { sector: sector }

expect(rendered).not_to include("fa-star")
expect(rendered).to include(DomainTheme.bg_class_for(:sectors))
end

it "marks a primary sector with a darker-green chip and a star" do
render partial: "sectors/tagging_label", locals: { sector: sector, is_primary: true }

expect(rendered).to include("fa-star")
expect(rendered).to include("bg-lime-200")
end
end