diff --git a/Gemfile b/Gemfile index a26be3baf..aa67caa0b 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,9 @@ gem "turbo-rails" # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] gem "stimulus-rails" +# A framework for creating reusable, testable & encapsulated view components +gem "view_component" + # Build JSON APIs with ease [https://github.com/rails/jbuilder] gem "jbuilder" diff --git a/Gemfile.lock b/Gemfile.lock index 6a3c37deb..75e4c61b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -443,6 +443,10 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.4.2) + view_component (3.7.0) + activesupport (>= 5.2.0, < 8.0) + concurrent-ruby (~> 1.0) + method_source (~> 1.0) warden (1.2.9) rack (>= 2.0.9) web-console (4.2.0) @@ -516,6 +520,7 @@ DEPENDENCIES traceroute turbo-rails tzinfo-data + view_component web-console RUBY VERSION diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss index 2953fee98..21a7b34c9 100644 --- a/app/assets/stylesheets/custom.scss +++ b/app/assets/stylesheets/custom.scss @@ -1,7 +1,7 @@ /** * Custom Styling * ----------------------------------------------------------------------------- -* [NOTE] Please avoid writing custom css if you can help it! +* [NOTE] Please avoid writing custom css if you can help it! * Prefer to use the Bootstrap utility classes to override styles or follow * the theme. * ----------------------------------------------------------------------------- @@ -9,3 +9,7 @@ label.required:after { content: " *"; } + +.cursor-pointer { + cursor: pointer; +} diff --git a/app/components/avatar_component.rb b/app/components/avatar_component.rb new file mode 100644 index 000000000..b22f49d63 --- /dev/null +++ b/app/components/avatar_component.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Use Avatar::Component to represent users with image or initials. +class AvatarComponent < ViewComponent::Base + SIZES = { + x_small: "avatar-xs", + small: "avatar-sm", + medium: "avatar-md", + large: "avatar-lg", + x_large: "avatar-xl", + xx_large: "avatar-xxl" + }.freeze + + # + # @example 1|Show avatar with initials + # <%= component "avatar", alt: "JT" %> + # + # @example 2|Show avatar with image_tag + # <%= component "avatar", src: "avatar_#{@order.subject.gender}.svg", + # size: :medium) %> + # + # @example 2|Show avatar with image_tag with default params + # <%= component "avatar", src: "avatar_#{@order.subject.gender}.svg"%> + # + # @param src [String] Specifies the URL of the image. + # @param alt[String] Alternate text for an image, if the image cannot be displayed. + + def initialize(alt: "avatar", size: :medium, **system_arguments) + @alt = alt + @system_arguments = system_arguments + @classes = "rounded-circle cursor-pointer avatar #{SIZES.fetch(size)}" + end + + def avatar_with_image + image_tag @system_arguments[:src], class: @classes, alt: @alt + end + + def avatar_with_initials + tag.div(tag.span(@alt), class: @classes, style: "background-color: #{avatar_color(@alt)}; display: flex; align-items: center; justify-content: center;") + end + + def avatar_color(text) + avatar_colors = ["#feb2b2", "#b3e4fc", "#d6bcfa", "#faf089", "#9ae6b4", "#f0e2ba", "#fbb6ce", "#dadada"] + + avatar_colors[text.ord % avatar_colors.length] + end + + def call + if @system_arguments[:src].present? + avatar_with_image + else + avatar_with_initials + end + end +end diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 90ee61c6e..e3c390f00 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -27,18 +27,18 @@
<%= f.email_field :email, autofocus: true, autocomplete: "email", - class: 'form-control' %> + class: 'form-control' %>
<% if devise_mapping.confirmable? && - resource.pending_reconfirmation? %> + resource.pending_reconfirmation? %>
Currently waiting confirmation for: - <%= resource.unconfirmed_email %>
+ <%= resource.unconfirmed_email %> <% end %>
<%= f.password_field :password, autocomplete: "new-password", - class: 'form-control', label: 'New password' %> + class: 'form-control', label: 'New password' %> (leave blank if you don't want to change it)
<% if @minimum_password_length %> <%= @minimum_password_length %> characters minimum @@ -47,24 +47,24 @@
<%= f.password_field :password_confirmation, autocomplete: "new-password", - class: 'form-control', label: 'Confirm new password' %> + class: 'form-control', label: 'Confirm new password' %>
<%= f.text_field :first_name, - class: 'form-control' %> + class: 'form-control' %>
<%= f.text_field :last_name, - class: 'form-control' %> + class: 'form-control' %>
<%= f.password_field :current_password, - autocomplete: "current-password", - required: true, - class: 'form-control' %> + autocomplete: "current-password", + required: true, + class: 'form-control' %> (we need your current password to confirm your changes)
@@ -72,7 +72,7 @@
<%= f.submit "Update", class: 'btn btn-outline-dark mt-3 mb-3', - data: { turbo: false } %> + data: { turbo: false } %>
<% end %>
@@ -90,20 +90,15 @@ data-delete-target="input" class="form-control mt-2"> <%= button_to "Delete my account", registration_path(resource_name), - class: 'btn custom-btn-pink mt-3 mb-3', - data: { confirm: 'Are you sure?', - turbo: 'false', - delete_target: 'button' }, - method: 'delete', - disabled: true %> + class: 'btn custom-btn-pink mt-3 mb-3', + data: { confirm: 'Are you sure?', + turbo: 'false', + delete_target: 'button' }, + method: 'delete', + disabled: true %> - - - - - diff --git a/app/views/layouts/dashboard.html.erb b/app/views/layouts/dashboard.html.erb index 4a6559f49..7bdb37ce1 100644 --- a/app/views/layouts/dashboard.html.erb +++ b/app/views/layouts/dashboard.html.erb @@ -180,17 +180,11 @@