From 0312383bc882c63c139fd2808aaabf678070513c Mon Sep 17 00:00:00 2001 From: songtianlun Date: Tue, 11 Feb 2025 15:52:58 +0800 Subject: [PATCH] feat: add flash message functionality - Implement Stimulus controller for closing flash messages - Replace inline alerts with a partial for better organization - Enhance styling for user registration and login forms This update introduces a new flash message component that allows for user notifications to be displayed on the screen and closed by the user. The forms also include improved styles for a better user experience. --- .../controllers/flash_controller.js | 8 ++ app/javascript/controllers/index.js | 8 +- app/views/devise/registrations/edit.html.erb | 123 ++++++++++++------ app/views/devise/sessions/new.html.erb | 84 +++++++++--- app/views/layouts/_flash_message.html.erb | 37 ++++++ app/views/layouts/_navbar.html.erb | 44 ++++++- app/views/layouts/application.html.erb | 20 +-- 7 files changed, 238 insertions(+), 86 deletions(-) create mode 100644 app/javascript/controllers/flash_controller.js create mode 100644 app/views/layouts/_flash_message.html.erb diff --git a/app/javascript/controllers/flash_controller.js b/app/javascript/controllers/flash_controller.js new file mode 100644 index 0000000..20cf7a9 --- /dev/null +++ b/app/javascript/controllers/flash_controller.js @@ -0,0 +1,8 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + close(event) { + const target = event.target.closest('.alert') + target.remove() + } +} \ No newline at end of file diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 40cfc50..e099ff0 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -3,12 +3,10 @@ // ./bin/rails generate stimulus controllerName import { application } from "./application" - import HelloController from "./hello_controller" -application.register("hello", HelloController) - import PhotoSwipeLightBoxController from "./photo_swipe_lightbox_controller" +import FlashMessageController from "./flash_controller" -console.log("ready to register photo-swipe") +application.register("hello", HelloController) application.register("photo-swipe-lightbox", PhotoSwipeLightBoxController) -console.log("successful to register photo-swipe") +application.register("flash", FlashMessageController) diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index b82e336..12398a8 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -1,43 +1,86 @@ -

Edit <%= resource_name.to_s.humanize %>

+
+
+
+
+

Account Settings

-<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> - <%= render "devise/shared/error_messages", resource: resource %> + <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: "space-y-6" }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> -
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email" %> +
+ <%= f.label :email, class: "label" %> + <%= f.email_field :email, + autofocus: true, + autocomplete: "email", + class: "input input-bordered w-full" %> +
+ + <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> +
+ + Currently waiting confirmation for: <%= resource.unconfirmed_email %> +
+ <% end %> + +
Change Password
+ +
+ <%= f.label :password, class: "label" do %> + New Password + (leave blank if you don't want to change it) + <% end %> + <%= f.password_field :password, + autocomplete: "new-password", + class: "input input-bordered w-full" %> + <% if @minimum_password_length %> + + <% end %> +
+ +
+ <%= f.label :password_confirmation, "Confirm New Password", class: "label" %> + <%= f.password_field :password_confirmation, + autocomplete: "new-password", + class: "input input-bordered w-full" %> +
+ +
+ <%= f.label :current_password, class: "label" do %> + Current Password + (required to confirm changes) + <% end %> + <%= f.password_field :current_password, + autocomplete: "current-password", + class: "input input-bordered w-full" %> +
+ +
+ <%= f.submit "Update Account", class: "btn btn-primary" %> +
+ <% end %> + +
Danger Zone
+ +
+

Delete Account

+

Once you delete your account, there is no going back. Please be certain.

+ <%= button_to registration_path(resource_name), + class: "btn btn-error", + data: { + confirm: "Are you sure?", + turbo_confirm: "Are you sure you want to delete your account? This action cannot be undone." + }, + method: :delete do %> + Delete Account + <% end %> +
+ +
+ <%= link_to "← Back", :back, class: "btn btn-ghost btn-sm" %> +
+
+
- - <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> -
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
- <% end %> - -
- <%= f.label :password %> (leave blank if you don't want to change it)
- <%= f.password_field :password, autocomplete: "new-password" %> - <% if @minimum_password_length %> -
- <%= @minimum_password_length %> characters minimum - <% end %> -
- -
- <%= f.label :password_confirmation %>
- <%= f.password_field :password_confirmation, autocomplete: "new-password" %> -
- -
- <%= f.label :current_password %> (we need your current password to confirm your changes)
- <%= f.password_field :current_password, autocomplete: "current-password" %> -
- -
- <%= f.submit "Update" %> -
-<% end %> - -

Cancel my account

- -
Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
- -<%= link_to "Back", :back %> +
\ No newline at end of file diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 5ede964..05823ad 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,26 +1,68 @@ -

Log in

+
+
+
+

Sign in to your account

-<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> -
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email" %> -
+ <%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "space-y-4" }) do |f| %> +
+ <%= f.label :email, class: "label" %> + <%= f.email_field :email, + autofocus: true, + autocomplete: "email", + class: "input input-bordered w-full", + placeholder: "your@email.com" %> +
-
- <%= f.label :password %>
- <%= f.password_field :password, autocomplete: "current-password" %> -
+
+
+ <%= f.label :password, class: "label" %> + <% if devise_mapping.recoverable? %> + <%= link_to "Forgot password?", new_password_path(resource_name), class: "label-text-alt link link-primary" %> + <% end %> +
+ <%= f.password_field :password, + autocomplete: "current-password", + class: "input input-bordered w-full", + placeholder: "••••••••" %> +
- <% if devise_mapping.rememberable? %> -
- <%= f.check_box :remember_me %> - <%= f.label :remember_me %> + <% if devise_mapping.rememberable? %> +
+ +
+ <% end %> + +
+ <%= f.submit "Sign in", class: "btn btn-primary w-full" %> +
+ <% end %> + + <% if devise_mapping.registerable? %> +
OR
+ +
+

+ Don't have an account? + <%= link_to "Create an account", new_registration_path(resource_name), class: "link link-primary" %> +

+
+ <% end %> + + <% if devise_mapping.omniauthable? %> +
+ <%- resource_class.omniauth_providers.each do |provider| %> + <%= button_to omniauth_authorize_path(resource_name, provider), + class: "btn btn-outline w-full", + data: { turbo: false } do %> + <%= image_tag("#{provider}.svg", class: "w-5 h-5 mr-2") if File.exist?(Rails.root.join("app/assets/images/#{provider}.svg")) %> + Sign in with <%= OmniAuth::Utils.camelize(provider) %> + <% end %> + <% end %> +
+ <% end %>
- <% end %> - -
- <%= f.submit "Log in" %>
-<% end %> - -<%= render "devise/shared/links" %> +
\ No newline at end of file diff --git a/app/views/layouts/_flash_message.html.erb b/app/views/layouts/_flash_message.html.erb new file mode 100644 index 0000000..dfc62a9 --- /dev/null +++ b/app/views/layouts/_flash_message.html.erb @@ -0,0 +1,37 @@ +
+ <% if notice %> +
+
+
+ + + + <%= notice %> +
+ +
+
+ <% end %> + + <% if alert %> +
+
+
+ + + + <%= alert %> +
+ +
+
+ <% end %> +
\ No newline at end of file diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb index 552aae4..260a0d5 100644 --- a/app/views/layouts/_navbar.html.erb +++ b/app/views/layouts/_navbar.html.erb @@ -5,9 +5,51 @@ Today AI Weather <% end %>
-
+
<%= link_to "Cities", cities_path, class: "btn btn-ghost font-sans" %> <%= link_to "Arts", arts_path, class: "btn btn-ghost font-sans" %> + + <% if user_signed_in? %> + + <% else %> + <%= link_to new_user_session_path, class: "btn btn-primary" do %> + + + + Sign in + <% end %> + <% end %>
\ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4471968..9515c72 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -59,25 +59,7 @@
-
- <% if notice %> -
-
- - <%= notice %> -
-
- <% end %> - - <% if alert %> -
-
- - <%= alert %> -
-
- <% end %> -
+ <%= render 'layouts/flash_message' %> <%= yield %>