mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-05 05:25:24 +02:00
User Onboarding + Bug Fixes (#1352)
* Bump min supported date to 20 years * Add basic onboarding * User onboarding * Complete onboarding flow * Cleanup, add user profile update test
This commit is contained in:
parent
73e184ad3d
commit
1d20de770f
55 changed files with 1088 additions and 300 deletions
7
app/views/settings/_user_avatar.html.erb
Normal file
7
app/views/settings/_user_avatar.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<%# locals: (user:) %>
|
||||
|
||||
<% if user.profile_image.attached? %>
|
||||
<%= image_tag user.profile_image.variant(:thumbnail), class: "rounded-full w-full h-full object-cover" %>
|
||||
<% else %>
|
||||
<div class="text-white w-full h-full bg-gray-400 rounded-full flex items-center justify-center text-lg uppercase"><%= user.initial %></div>
|
||||
<% end %>
|
52
app/views/settings/_user_avatar_field.html.erb
Normal file
52
app/views/settings/_user_avatar_field.html.erb
Normal file
|
@ -0,0 +1,52 @@
|
|||
<%# locals: (form:, user:) %>
|
||||
|
||||
<div class="flex items-center gap-4" data-controller="profile-image-preview">
|
||||
<div class="relative flex justify-center items-center bg-gray-50 w-24 h-24 rounded-full border-alpha-black-300 border border-dashed">
|
||||
|
||||
<%# The image preview once user has uploaded a new file %>
|
||||
<div data-profile-image-preview-target="previewImage" class="h-full w-full flex justify-center items-center hidden">
|
||||
<img src="" alt="Preview" class="w-full h-full rounded-full object-cover">
|
||||
</div>
|
||||
|
||||
<%# The placeholder image for empty avatar field %>
|
||||
<div data-profile-image-preview-target="placeholderImage"
|
||||
class="h-full w-full flex justify-center items-center <%= user.profile_image.attached? ? "hidden" : "" %>">
|
||||
<div class="h-full w-full flex justify-center items-center">
|
||||
<%= lucide_icon "image-plus", class: "w-6 h-6 text-gray-500" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%# The attached image if user has already uploaded one %>
|
||||
<div data-profile-image-preview-target="attachedImage"
|
||||
class="h-full w-full flex justify-center items-center <%= user.profile_image.attached? ? "" : "hidden" %>">
|
||||
<% if user.profile_image.attached? %>
|
||||
<div class="h-full w-full">
|
||||
<%= render "settings/user_avatar", user: user %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<button type="button"
|
||||
data-profile-image-preview-target="clearBtn"
|
||||
data-action="click->profile-image-preview#clearFileInput"
|
||||
class="<%= user.profile_image.attached? ? "" : "hidden" %> cursor-pointer absolute bottom-0 right-0 w-8 h-8 bg-gray-50 rounded-full flex justify-center items-center border border-white border-2">
|
||||
<%= lucide_icon "x", class: "w-4 h-4 text-gray-500" %>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= form.hidden_field :delete_profile_image, value: "0", data: { profile_image_preview_target: "deleteProfileImage" } %>
|
||||
|
||||
<p class="mb-3"><%= t(".accepted_formats") %></p>
|
||||
|
||||
<%= form.label :profile_image, t(".choose"),
|
||||
class: "btn btn--outline inline-block" %>
|
||||
<%= form.file_field :profile_image,
|
||||
accept: "image/png, image/jpeg",
|
||||
class: "hidden px-3 py-2 bg-gray-50 text-gray-900 rounded-md text-sm font-medium",
|
||||
data: {
|
||||
profile_image_preview_target: "input",
|
||||
action: "change->profile-image-preview#showFileInputPreview"
|
||||
} %>
|
||||
</div>
|
||||
</div>
|
|
@ -5,7 +5,7 @@
|
|||
<div class="space-y-4">
|
||||
<h1 class="text-gray-900 text-xl font-medium mb-4"><%= t(".page_title") %></h1>
|
||||
<%= settings_section title: t(".subscription_title"), subtitle: t(".subscription_subtitle") do %>
|
||||
<% if Current.family.stripe_plan_id.blank? %>
|
||||
<% if @user.family.stripe_plan_id.blank? %>
|
||||
<%= link_to t(".subscribe_button"), new_subscription_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2", data: { turbo: false } %>
|
||||
<% else %>
|
||||
<%= link_to t(".manage_subscription_button"), subscription_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2", data: { turbo: false } %>
|
||||
|
|
|
@ -6,16 +6,28 @@
|
|||
<h1 class="text-gray-900 text-xl font-medium mb-4"><%= t(".page_title") %></h1>
|
||||
<%= settings_section title: t(".general_title"), subtitle: t(".general_subtitle") do %>
|
||||
<div>
|
||||
<%= styled_form_with model: Current.user, url: settings_preferences_path, class: "space-y-4", data: { controller: "auto-submit-form" } do |form| %>
|
||||
<%= form.fields_for :family_attributes do |family_form| %>
|
||||
<%= styled_form_with model: @user, class: "space-y-4", data: { controller: "auto-submit-form" } do |form| %>
|
||||
<%= form.hidden_field :redirect_to, value: "preferences" %>
|
||||
|
||||
<%= form.fields_for :family do |family_form| %>
|
||||
<%= family_form.select :currency,
|
||||
currencies_for_select.map { |currency| [ "#{currency.name} (#{currency.iso_code})", currency.iso_code ] },
|
||||
{ label: "Currency", selected: Current.family.currency },
|
||||
{ label: t(".currency") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<%= family_form.select :locale,
|
||||
I18n.available_locales,
|
||||
{ label: "Locale", selected: Current.family.locale },
|
||||
language_options,
|
||||
{ label: t(".language") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<%= family_form.select :date_format,
|
||||
date_format_options,
|
||||
{ label: t(".date_format") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<%= family_form.select :country,
|
||||
country_options,
|
||||
{ label: t(".country") },
|
||||
{ data: { auto_submit_form_target: "auto" } } %>
|
||||
|
||||
<p class="text-xs italic pl-2 text-gray-500">Please note, we are still working on translations for various languages. Please see the <%= link_to "I18n issue", "https://github.com/maybe-finance/maybe/issues/1225", target: "_blank", class: "underline" %> for more information.</p>
|
||||
|
@ -25,7 +37,8 @@
|
|||
<% end %>
|
||||
<%= settings_section title: t(".theme_title"), subtitle: t(".theme_subtitle") do %>
|
||||
<div>
|
||||
<%= styled_form_with model: Current.user, url: settings_preferences_path, local: true, class: "flex justify-between items-center" do |form| %>
|
||||
<%= styled_form_with model: @user, class: "flex justify-between items-center" do |form| %>
|
||||
<%= form.hidden_field :redirect_to, value: "preferences" %>
|
||||
<div class="text-center">
|
||||
<%= image_tag("light-mode-preview.png", alt: "Light Theme Preview", class: "h-44 mb-4") %>
|
||||
<div class="flex justify-center items-center gap-2">
|
||||
|
|
|
@ -5,35 +5,13 @@
|
|||
<h1 class="text-gray-900 text-xl font-medium mb-4"><%= t(".page_title") %></h1>
|
||||
<div class="space-y-4">
|
||||
<%= settings_section title: t(".profile_title"), subtitle: t(".profile_subtitle") do %>
|
||||
<%= styled_form_with model: Current.user, url: settings_profile_path, class: "space-y-4", data: { controller: "profile-image-preview" } do |form| %>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="relative flex justify-center items-center bg-gray-50 w-24 h-24 rounded-full border border-alpha-black-25">
|
||||
<div data-profile-image-preview-target="imagePreview" class="h-full w-full flex justify-center items-center">
|
||||
<% profile_image_attached = Current.user.profile_image.attached? %>
|
||||
<% if profile_image_attached %>
|
||||
<div class="h-24 w-24">
|
||||
<%= render "shared/user_profile_image", user: Current.user %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= lucide_icon "image-plus", class: "w-6 h-6 text-gray-500" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= lucide_icon "image-plus", class: "hidden w-6 h-6 text-gray-500", data: { profile_image_preview_target: "template" } %>
|
||||
<div data-profile-image-preview-target="clearBtn" data-action="click->profile-image-preview#clear" class="<%= profile_image_attached ? "" : "hidden" %> cursor-pointer absolute bottom-0 right-0 w-8 h-8 bg-gray-50 rounded-full flex justify-center items-center border border-white border-2">
|
||||
<%= lucide_icon "x", class: "w-4 h-4 text-gray-500" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<p><%= t(".profile_image_type") %></p>
|
||||
<%= form.label :profile_image, t(".profile_image_choose"), class: "inline-block cursor-pointer px-3 py-2 bg-gray-50 text-gray-900 rounded-md text-sm font-medium" %>
|
||||
<%= form.file_field :profile_image, accept: "image/png, image/jpeg", class: "hidden px-3 py-2 bg-gray-50 text-gray-900 rounded-md text-sm font-medium", data: {profile_image_preview_target: "fileField", action: "change->profile-image-preview#preview"} %>
|
||||
<%= form.hidden_field :delete_profile_image, value: false, data: {profile_image_preview_target: "deleteField"} %>
|
||||
</div>
|
||||
</div>
|
||||
<%= styled_form_with model: @user, class: "space-y-4" do |form| %>
|
||||
<%= render "settings/user_avatar_field", form: form, user: @user %>
|
||||
|
||||
<div>
|
||||
<div class="grid grid-cols-2 gap-4 mt-4">
|
||||
<%= form.text_field :first_name, placeholder: "First name", value: Current.user.first_name, label: true %>
|
||||
<%= form.text_field :last_name, placeholder: "Last name", value: Current.user.last_name, label: true %>
|
||||
<%= form.text_field :first_name, placeholder: t(".first_name"), label: t(".first_name") %>
|
||||
<%= form.text_field :last_name, placeholder: t(".last_name"), label: t(".last_name") %>
|
||||
</div>
|
||||
<div class="flex justify-end mt-4">
|
||||
<%= form.submit t(".save"), class: "bg-gray-900 hover:bg-gray-700 cursor-pointer text-white rounded-lg px-3 py-2" %>
|
||||
|
@ -43,9 +21,13 @@
|
|||
<% end %>
|
||||
<%= settings_section title: t(".household_title"), subtitle: t(".household_subtitle") do %>
|
||||
<div class="space-y-4">
|
||||
<%= styled_form_with model: Current.user, url: settings_profile_path, class: "space-y-4", data: { controller: "auto-submit-form", "auto-submit-form-trigger-event-value": "blur" } do |form| %>
|
||||
<%= form.fields_for :family_attributes do |family_fields| %>
|
||||
<%= family_fields.text_field :name, placeholder: t(".household_form_input_placeholder"), value: Current.family.name, label: t(".household_form_label"), disabled: !Current.user.admin?, "data-auto-submit-form-target": "auto" %>
|
||||
<%= styled_form_with model: Current.user, class: "space-y-4", data: { controller: "auto-submit-form" } do |form| %>
|
||||
<%= form.fields_for :family do |family_fields| %>
|
||||
<%= family_fields.text_field :name,
|
||||
placeholder: t(".household_form_input_placeholder"),
|
||||
label: t(".household_form_label"),
|
||||
disabled: !Current.user.admin?,
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<div class="bg-gray-25 rounded-xl p-1">
|
||||
|
@ -71,7 +53,7 @@
|
|||
<p class="text-gray-500 text-sm"><%= t(".delete_account_warning") %></p>
|
||||
</div>
|
||||
<%=
|
||||
button_to t(".delete_account"), settings_profile_path, method: :delete,
|
||||
button_to t(".delete_account"), user_path(@user), method: :delete,
|
||||
class: "bg-red-500 text-white text-sm font-medium rounded-lg px-3 py-2",
|
||||
data: { turbo_confirm: {
|
||||
title: t(".confirm_delete.title"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue