From 1b0e6b1765a34d0babb2fae41f909eb2c2a5b012 Mon Sep 17 00:00:00 2001 From: Yuri Sidorov <403994+newstler@users.noreply.github.com> Date: Mon, 9 Feb 2026 22:11:30 +0100 Subject: [PATCH 01/11] Redesign profile settings as dropdown, UI refinements Move profile settings into a collapsible dropdown menu on user show page (both desktop and mobile). Reorder toggles to place newsletter before open-to-work, rename "Newsletter" to "Receive news". Replace "Sort:" text labels with sort icon SVG. Adjust avatar sizes on community index and testimonial heading styling. Co-Authored-By: Claude Opus 4.6 --- app/assets/images/sort.svg | 3 + app/views/users/_profile_settings.html.erb | 34 +++++------ app/views/users/index.html.erb | 6 +- app/views/users/show.html.erb | 71 +++++++++++++--------- 4 files changed, 66 insertions(+), 48 deletions(-) create mode 100644 app/assets/images/sort.svg diff --git a/app/assets/images/sort.svg b/app/assets/images/sort.svg new file mode 100644 index 0000000..c8b687e --- /dev/null +++ b/app/assets/images/sort.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/views/users/_profile_settings.html.erb b/app/views/users/_profile_settings.html.erb index 2bb9b80..256e7e4 100644 --- a/app/views/users/_profile_settings.html.erb +++ b/app/views/users/_profile_settings.html.erb @@ -1,6 +1,6 @@ -
+
<%# Public Profile Toggle %> -
+
Public profile <%= button_to toggle_public_user_settings_path, method: :post, @@ -12,34 +12,34 @@ <% end %>
- <%# Open to Work Toggle %> -
- Open to work - <%= button_to toggle_open_to_work_user_settings_path, + <%# Newsletter Toggle %> +
+ Receive news + <%= button_to toggle_newsletter_user_settings_path, method: :post, - class: "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 #{user.open_to_work? ? 'bg-red-600' : 'bg-gray-400'}", + class: "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 #{user.unsubscribed_from_newsletter? ? 'bg-gray-400' : 'bg-red-600'}", data: { turbo_stream: true } do %> - Toggle open to work + Toggle newsletter subscription + class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out <%= user.unsubscribed_from_newsletter? ? 'translate-x-0' : 'translate-x-4' %>"> <% end %>
- <%# Newsletter Toggle %> -
- Newsletter - <%= button_to toggle_newsletter_user_settings_path, + <%# Open to Work Toggle %> +
+ Open to work + <%= button_to toggle_open_to_work_user_settings_path, method: :post, - class: "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 #{user.unsubscribed_from_newsletter? ? 'bg-gray-400' : 'bg-red-600'}", + class: "relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 #{user.open_to_work? ? 'bg-red-600' : 'bg-gray-400'}", data: { turbo_stream: true } do %> - Toggle newsletter subscription + Toggle open to work + class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out <%= user.open_to_work? ? 'translate-x-4' : 'translate-x-0' %>"> <% end %>
<%# Sign Out Button %> -
+
<%= button_to "Sign out", destroy_user_session_path, method: :delete, data: { turbo: false }, diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index bcfc0c0..4fe2ea7 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -61,7 +61,7 @@ <%= number_with_delimiter(@total_users_count) %>

<%= t('users.index.developer_count', count: @total_users_count) %>

<%= link_to community_user_url(current_user), class: "group sm:hidden ml-auto self-center", data: { turbo_frame: "_top" } do %> - <%= render "shared/gem_avatar", user: current_user, size: "w-10 h-9", badge_size: "map", thick_border: true %> + <%= render "shared/gem_avatar", user: current_user, size: "w-12 h-[43px]", badge_size: "tiny", thick_border: true %> <% end %>

@@ -106,7 +106,7 @@ <% if user_signed_in? %>

<% unless current_user.testimonial&.published? %> @@ -129,7 +129,7 @@ <% end %>
<%= render "users/profile_stars", user: @user %>
- - - <% if @user.bio.present? %> -

title="To update your bio, company, location or contacts, edit them on GitHub — changes sync here automatically within a day."<% end %>><%= sanitize(@user.bio_html.presence || linkify_bio(@user.bio), tags: %w[a], attributes: %w[href target rel class]) %>

- <% end %> - - -
- <% if @user.company.present? %> - <%= link_to community_index_path(company: @user.company), class: "flex items-center hover:text-gray-600 transition-colors" do %> - <%= inline_svg_tag "building.svg", class: "w-4 h-4 mr-1" %> - <%= @user.company %> - <% end %> - <% end %> - <% if @user.location.present? %> - <%= link_to community_index_path(location: @user.normalized_location || @user.location), class: "flex items-center hover:text-gray-600 transition-colors" do %> - <%= inline_svg_tag "location.svg", class: "w-4 h-4 mr-1" %> - <%= @user.location %> + +
+
+ <% if @user.bio.present? %> +

title="To update your bio, company, location or contacts, edit them on GitHub — changes sync here automatically within a day."<% end %>><%= sanitize(@user.bio_html.presence || linkify_bio(@user.bio), tags: %w[a], attributes: %w[href target rel class]) %>

<% end %> +
+ <% if @user.company.present? %> + <%= link_to community_index_path(company: @user.company), class: "flex items-center hover:text-gray-600 transition-colors" do %> + <%= inline_svg_tag "building.svg", class: "w-4 h-4 mr-1" %> + <%= @user.company %> + <% end %> + <% end %> + <% if @user.location.present? %> + <%= link_to community_index_path(location: @user.normalized_location || @user.location), class: "flex items-center hover:text-gray-600 transition-colors" do %> + <%= inline_svg_tag "location.svg", class: "w-4 h-4 mr-1" %> + <%= @user.location %> + <% end %> + <% end %> +
+
+ <% if current_user == @user %> +
+ + +
<% end %>
- - - <% if current_user == @user %> -
- <%= render "users/profile_settings", user: @user, wrapper_id: "profile_settings_desktop" %> -
- <% end %>
@@ -180,7 +186,16 @@ <% if current_user == @user %>
- <%= render "users/profile_settings", user: @user, wrapper_id: "profile_settings_mobile" %> +
+ + +
<% end %>
@@ -196,7 +211,7 @@ <%= render "testimonials/section", testimonial: testimonial, user: @user %> <% elsif testimonial&.published? %>
-

loves Ruby because of...

+

loves Ruby because of...

<%= render "testimonials/testimonial", testimonial: testimonial %>
<% end %> @@ -275,7 +290,7 @@ diff --git a/app/views/shared/_gem_avatar.html.erb b/app/views/shared/_gem_avatar.html.erb index 68dd731..2544e48 100644 --- a/app/views/shared/_gem_avatar.html.erb +++ b/app/views/shared/_gem_avatar.html.erb @@ -12,6 +12,7 @@ <% show_badge = local_assigns.key?(:show_open_to_work) ? show_open_to_work : user.open_to_work? %> <% small_badge = local_assigns[:badge_size] == "small" %> <% tiny_badge = local_assigns[:badge_size] == "tiny" %> +<% xs_badge = local_assigns[:badge_size] == "xs" %> <% map_badge = local_assigns[:badge_size] == "map" %> <% thick_border = local_assigns[:thick_border] == true %>
@@ -45,6 +46,10 @@
Open to work
+ <% elsif xs_badge %> +
+ Open to work +
<% else %>
From ecf3539a783e701b6acda85d40d366cc04258d91 Mon Sep 17 00:00:00 2001 From: Yuri Sidorov <403994+newstler@users.noreply.github.com> Date: Mon, 9 Feb 2026 22:54:03 +0100 Subject: [PATCH 03/11] Fix char counter submit target guard, conditional mobile menu controller Add hasSubmitTarget check in char_counter_controller to prevent errors when submit target is absent. Skip mobile-menu Stimulus controller on nav_minimal pages. Co-Authored-By: Claude Opus 4.6 --- .../controllers/char_counter_controller.js | 18 ++++++++++-------- app/views/layouts/application.html.erb | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/javascript/controllers/char_counter_controller.js b/app/javascript/controllers/char_counter_controller.js index 031a9bb..19b1323 100644 --- a/app/javascript/controllers/char_counter_controller.js +++ b/app/javascript/controllers/char_counter_controller.js @@ -28,14 +28,16 @@ export default class extends Controller { colorClass = `${pill} bg-red-100 text-red-600` } - if (isValid) { - this.submitTarget.disabled = false - this.submitTarget.classList.remove("opacity-50", "cursor-not-allowed") - this.submitTarget.classList.add("cursor-pointer", "hover:bg-red-700") - } else { - this.submitTarget.disabled = true - this.submitTarget.classList.add("opacity-50", "cursor-not-allowed") - this.submitTarget.classList.remove("cursor-pointer", "hover:bg-red-700") + if (this.hasSubmitTarget) { + if (isValid) { + this.submitTarget.disabled = false + this.submitTarget.classList.remove("opacity-50", "cursor-not-allowed") + this.submitTarget.classList.add("cursor-pointer", "hover:bg-red-700") + } else { + this.submitTarget.disabled = true + this.submitTarget.classList.add("opacity-50", "cursor-not-allowed") + this.submitTarget.classList.remove("cursor-pointer", "hover:bg-red-700") + } } this.counterTargets.forEach(counter => { diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 748331d..9a16d56 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -90,7 +90,7 @@ <% community_nav = content_for?(:nav_community_style) || (controller_name == 'users' && ['index', 'show'].include?(action_name)) %> -