From be1f76a76d25861c7f09039602bf728c5acf57dd Mon Sep 17 00:00:00 2001 From: songtianlun Date: Tue, 11 Feb 2025 16:43:05 +0800 Subject: [PATCH] feat: enhance devise views with new styling - Updated confirmation, password, unlock, and session views to use a card-based layout for improved visual appeal. - Added responsive design features to ensure compatibility across devices. - Enhanced usability by providing clear placeholders in form fields. These changes improve the user experience during account recovery and management processes. The design promotes a modern interface while maintaining functionality. --- app/views/devise/confirmations/new.html.erb | 46 +++++++++++----- app/views/devise/passwords/edit.html.erb | 58 +++++++++++++-------- app/views/devise/passwords/new.html.erb | 39 +++++++++----- app/views/devise/sessions/new.html.erb | 19 +------ app/views/devise/shared/_links.html.erb | 14 ++--- app/views/devise/unlocks/new.html.erb | 44 +++++++++++----- config/credentials.yml.enc | 2 +- config/environments/production.rb | 13 ++++- config/initializers/devise.rb | 10 ++-- 9 files changed, 153 insertions(+), 92 deletions(-) diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb index b12dd0c..4ea8264 100644 --- a/app/views/devise/confirmations/new.html.erb +++ b/app/views/devise/confirmations/new.html.erb @@ -1,16 +1,36 @@ -

Resend confirmation instructions

+
+
+
+

Resend confirmation instructions

-<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> - <%= render "devise/shared/error_messages", resource: resource %> +

+ Didn't receive confirmation instructions? Enter your email below to resend. +

-
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> + <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email, class: "label" %> + <%= f.email_field :email, + autofocus: true, + autocomplete: "email", + value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), + class: "input input-bordered w-full", + placeholder: "Enter your email" %> +
+ +
+ <%= f.submit "Resend confirmation instructions", + class: "btn btn-primary w-full" %> +
+ <% end %> + +
+ +
+ <%= render "devise/shared/links" %> +
+
- -
- <%= f.submit "Resend confirmation instructions" %> -
-<% end %> - -<%= render "devise/shared/links" %> +
\ No newline at end of file diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index 5fbb9ff..72941f7 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -1,25 +1,39 @@ -

Change your password

+
+
+
+

Change your password

-<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> - <%= render "devise/shared/error_messages", resource: resource %> - <%= f.hidden_field :reset_password_token %> + <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + <%= f.hidden_field :reset_password_token %> -
- <%= f.label :password, "New password" %>
- <% if @minimum_password_length %> - (<%= @minimum_password_length %> characters minimum)
- <% end %> - <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %> +
+ <%= f.label :password, "New password", class: "label" %> + <% if @minimum_password_length %> + (<%= @minimum_password_length %> characters minimum) + <% end %> + <%= f.password_field :password, autofocus: true, autocomplete: "new-password", + class: "input input-bordered w-full", + placeholder: "Enter new password" %> +
+ +
+ <%= f.label :password_confirmation, "Confirm new password", class: "label" %> + <%= f.password_field :password_confirmation, autocomplete: "new-password", + class: "input input-bordered w-full", + placeholder: "Confirm new password" %> +
+ +
+ <%= f.submit "Change my password", class: "btn btn-primary w-full" %> +
+ <% end %> + +
+ +
+ <%= render "devise/shared/links" %> +
+
- -
- <%= f.label :password_confirmation, "Confirm new password" %>
- <%= f.password_field :password_confirmation, autocomplete: "new-password" %> -
- -
- <%= f.submit "Change my password" %> -
-<% end %> - -<%= render "devise/shared/links" %> +
\ No newline at end of file diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb index 9b486b8..fe548b4 100644 --- a/app/views/devise/passwords/new.html.erb +++ b/app/views/devise/passwords/new.html.erb @@ -1,16 +1,29 @@ -

Forgot your password?

+
+
+
+

Forgot your password?

-<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> - <%= render "devise/shared/error_messages", resource: resource %> + <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) 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", + placeholder: "Enter your email" %> +
+ +
+ <%= f.submit "Send me reset password instructions", + class: "btn btn-primary w-full" %> +
+ <% end %> + +
+ +
+ <%= render "devise/shared/links" %> +
+
- -
- <%= f.submit "Send me reset password instructions" %> -
-<% end %> - -<%= render "devise/shared/links" %> +
\ 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 05823ad..b4b184d 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -43,26 +43,11 @@ <% if devise_mapping.registerable? %>
OR
-
-

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

+
+ <%= render "devise/shared/links" %>
<% 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 %>
\ No newline at end of file diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb index bbd0ccd..dc2663d 100644 --- a/app/views/devise/shared/_links.html.erb +++ b/app/views/devise/shared/_links.html.erb @@ -1,32 +1,32 @@
<%- if controller_name != 'sessions' %> - <%= link_to "Sign in", new_session_path(resource_name), class: "link link-primary" %> +

<%= link_to "Sign in", new_session_path(resource_name), class: "link link-primary" %>

<% end %> <%- if devise_mapping.registerable? && controller_name != 'registrations' %> - <%= link_to "Create an account", new_registration_path(resource_name), class: "link link-primary" %> +

<%= link_to "Create an account", new_registration_path(resource_name), class: "link link-primary" %>

<% end %> <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> - <%= link_to "Forgot your password?", new_password_path(resource_name), class: "link link-primary" %> +

<%= link_to "Forgot your password?", new_password_path(resource_name), class: "link link-primary" %>

<% end %> <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: "link link-secondary text-sm" %> +

<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: "link link-secondary text-sm" %>

<% end %> <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: "link link-secondary text-sm" %> +

<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: "link link-secondary text-sm" %>

<% end %> <%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %> - <%= button_to omniauth_authorize_path(resource_name, provider), +

<%= button_to omniauth_authorize_path(resource_name, provider), class: "btn btn-outline w-full gap-2", data: { turbo: false } do %> <%= image_tag("#{provider}.svg", class: "w-5 h-5") if File.exist?(Rails.root.join("app/assets/images/#{provider}.svg")) %> - Sign in with <%= OmniAuth::Utils.camelize(provider) %> + Sign in with <%= OmniAuth::Utils.camelize(provider) %>

<% end %> <% end %>
diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb index ffc34de..3830f7d 100644 --- a/app/views/devise/unlocks/new.html.erb +++ b/app/views/devise/unlocks/new.html.erb @@ -1,16 +1,34 @@ -

Resend unlock instructions

+
+
+
+

Unlock Account

-<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> - <%= render "devise/shared/error_messages", resource: resource %> +

+ Your account has been locked due to too many failed login attempts. + Enter your email to receive unlock instructions. +

-
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email" %> + <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email, class: "label" %> + <%= f.email_field :email, autofocus: true, autocomplete: "email", + class: "input input-bordered w-full", + placeholder: "Enter your email" %> +
+ +
+ <%= f.submit "Resend unlock instructions", + class: "btn btn-primary w-full" %> +
+ <% end %> + +
+ +
+ <%= render "devise/shared/links" %> +
+
- -
- <%= f.submit "Resend unlock instructions" %> -
-<% end %> - -<%= render "devise/shared/links" %> +
\ No newline at end of file diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index 45f9aeb..75cc769 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -eq4Y6iazLmvUUO+x38IQUs2iC/Ti6GXAmFGcUSIxTxqhENoqTGSWfVCu34gV7pZAnwsvc6T/csaUYutI2SaY1bS692Dm5WAWPzvAXkR5aJtmRtt8v9GMuSxcMLLkpxPGQzTWO+lVnh6ecFAQDkh2takeSSlE5OW6i4kNwqouRmvfTRVkIhmOHDJR/pRkQbk6oPYNwcx477m7KPcX1gN2k4Et5id2liFlXE7k3x4Xli9SM4dWjIV67E7wabC5+0vbz5KmvuyBqt2URW8klhQheGecOlYV37XmO0lErV1zBP2lWB9pz9QqsHNe71EMvsPwhYtYVIEyDt322pEdT3FUFOa4XBGxu2MGQFb+8Ff3tCi/DYj/kJec37sP/zcHb59AgxCUJB0VENQqiaOu2u0NTCgjODbaYnoJws8IaNybGEaEzmJkGefFG03nEEpdSpxD5QPU4MJC+byihwkA8iGzO1bW4iW+oiIPgn4RHX7UR4ADx3jGTlDsAX1pQIvzZCnf2/eRTlgcfz+QXzbvQ7wBOIHGG6kMa6rhVwYf1s9RoD7+HlYNN/egcCqj9QshibM7JADdwAQebn3An+/8gmYmRKgxQtwBf/8XSMT0m2oSfldiS3D6+kRrL4tUNjSIHqWUSQPvZomAeZrH4QtuK5dKov9OSqoSwlMUBBc9N+GvFxKIpJDOKF8JWNKoQUv+5CUWoU+AndlJBAoBnvwJbdNC2w1ergaHoVKfdDA4NU6U/TAtEbwpSbnrtYTf8Mxb/7rX30Ck1tQEuxQHUhiRozFLe4qsOhI2fQ0VOJ1HEfxK0ttdmo8i5FnpQ8iqjFE0LsAhIe5fFYqOqIpRbu/Uyt3fgThUD9p3QqBVX0ZPwNVnlqQwYfpRnrv3VNKzn0h6slyd2/hZYRVr+S2VGqxJgE0AZqTLZLSojeXHGrA3kHT1m0ncaOKEJ0YnGF9mKcbm43ViC6wgPBudbqs6mF0RTfDsAyK0JcWA4f4ssVH7QvjZgqrXz5AD4mth7U9gOSQSLQ9wxbiZTY8Csa1ZGNx3oszscFQ5Tw85tpSkk/Fuv6/7QKcVy/uFEyhWGVeJwWrLXsAyYP1lwbwyixgWflXE6APBopeVVVB7fLpEZTHyUyo/MHLe4Lp2Yw1cd1K8HOi0nIdSnEbc3HlIWwEsleZ4APFonvw7/JPlsceWUqgqbtW2KP9EtW6abplSwC9z8AuF6iFkEGYD1LFp5wE2gboaLtfUyFr0Xw1LVH3hn15ku3p7ptihvMqnHk05ulNhBAk6MVS231koMb0xIRTaP7BaUu25i0rmJgerWw2BJdjsiBab32s5u7sWnWR8fMCD55tsFMyiEZQHp1InXUVx8GBtbE9K0dTAvcIS0mKH8+DY61R9HeJ46L7AX6BADOpug9ScjiE62owl7CR95M97V+B53muKVSXT9tnqsYYJqP3fVk8X264i97T2JxOKwAxPxoPljv9Y6nwH8ZlR7s1sPCviOQxZBssEkmTxiYjX9J0+S0T/q9M6NwYZn1weEjCPFZbwHltcXBTqPuvR0iUN+itUBTnDkS0F3CkF12JmfYWJSOAh3PR+sgEcrJszySxoGMEv3smUx7MgJ+eZWIkbXbx0JWzEf/UJIparRGYVP4GCerZ7EY6Q2HG4WkyR3v2A7Ityzv0jI/u3DDXoEIB/+tW7xaeSzTJjaLjO--wzTRxzkF39xx+3YB--yfEzFDCIT3kpIEDGL5skrQ== \ No newline at end of file +WIRCFJoA1YUpdSuljSkBqEJvBpftvTRGA73T9Oy9vXNnOIHcnZDHtlhh2VuF4Xtq41d0aPJ2qPI4kUeGzM34I6FITsSY6i1y5ZEW4vUa8F/BRTO0/viXBPiSAS+BkWVEWYrFkNWJAIitVLG0hq8vCBEEs/KctxY8w9h0LwgyRV2udPzn6A7wyoJhR/V5nRamU6USFiHh6cpTlFQdSIZ0sC6v21IIS+G/ZPJXNNTw2+gVaDfL1yuX1nrLsxeMsb30iugksDj/gCVi42kF/hPVOGIZCM1ftM5j4Q+BcTDyEVqIMeXRdtegLKWM5sI0yB070m7gMRK1Oewa3z+NuPLGp1Stuuo977LGuATmP3/GnAMEZe8tgMfeKYeQv2+TerpLmO07KayOzN3j0qSs/OqrcSUP+SByxRBmpmeXNEQ6q+f1ZDreo/Q1Cm+aZe1UWXYpcgd6MVGHjYUna4SgTQqUKHKdzvf7Yx8fOjrzHRqZ6Y8LWq53Vzr8oNJ9IoNAh9TSJMF4tR3M+OQ7+SARgwQLoVsehgK1Z658GMvhVoeLrPTwvdID54+TSFMepMnownDJPZGKZoZK1+NlUyzz3rJ2iH9AxZnvwPMCcmlHH/Fh/FANmtQxd3DIPpjHHyZjxFLsR9tNuIapXPK8SiRhWbtYo+4i0/dgUvD8SfECSOklfx2tVIhvxTjg4AM+WtI9gieDISq+AZe9fjqyv8vLOJuDX8Nk1k69DKIqB2u+OFJW2/PPYFz2Ry283ep+VRKwS2qlsFEkTRkzPJ5y9dVrCXIYl0R7vgC+GDrUkK1IffZmTaJ+rqmzzwLF1OwPdtN/QuJm0aZZQmN9pQgUjt1PEgthQVW9dt/ElDZKgVjIcds3F1kX0+ZWJQRvBldilC9W5lRSea/9x253dw3wj1ERF6sZsIJCwcxTJigTM4rEfcjrMnEIfiW1HWc1LTJ5DUIh5GISBv7NDF52voP2TBamAq2Zg2vVg2v+bU9ydkkIVOm4oLYZWDQyDBeQC4KJscFCSo1ZxvRuqIRtnI3h2KoXJeK63cxGcVxbHcyYO5xTPXmPkk18pFPYoXe46an6xTEzxYXQMfWuIUvM9oOjgZXFvdgPwDWzL/pSZb6qW5MiDqvlt38ddivUtsZLMMtpgZjXOAyKQyIQNSOHyrrYoj6r8PdFiCZMWjn1B0HmXgIl47jrb9o1nrif9rb5DSUY2Pvl0+TeRnUB8r7Wa+t+UdHjrq6PEaXVOQbej78Rzo5xmZ5XknlbKv02Vjpcm8EIkc00nKvMo29f0mr1Wv48CL+tuDxiW3v2yX8NcTnMEoQkTTaw5wJmSb3dmPdVZwjcCdbqs1CbRpc/ngX7nJP9kF2P57BWqqYq6V4fWk3vEgLpTUsTCbJvTlCx7McLKy2/smtz2HQl6Vs5jofpSIXgNC35TBkPP22XLFiBTah0E2IUeF2TyuLphswQsMDzKzADMxkKpzEVNLCzzKfygDfsfsJqZjKBGHJz3RHDbGoqmgP/4u7FEBV9gUXFt5i5k71HxSnafbpcFkLk3AdfNLso2qUNZSj/8EzY33WFjQIEAFJeTqB8WML/LcVvNqQqvjUyUMgvA+rZq+BwS8svqJEvcRFmZhjeqQbsYs+C+jOlwjrohoak/CgfiHofuXWvnNyi0+PT6bPO5CsjbpJLwFxbPi19tWmnMR7ZOqIE3vN4bf8Rjg4T5zhKKbgIU7wEP+i0u9p0zPFEa6EZMxp8/5q50EjXdlY/cHa/Sp05x2h8jhi1Trxgg8yFOdu2P+dStAwW3Sv4x2o=--aZKHys4Q3dCV2P+L--yEOdlrHAYleGIYmdKAB4FQ== \ No newline at end of file diff --git a/config/environments/production.rb b/config/environments/production.rb index 6bde9d3..0883b76 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -59,7 +59,18 @@ Rails.application.configure do # config.action_mailer.raise_delivery_errors = false # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "todayaiweather.com" } + config.action_mailer.default_url_options = { host: ENV.fetch("RAILS_BASE_URL", "todayaiweather.com") } + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { + address: "smtpdm.aliyun.com", + port: 465, + user_name: "noreply@mail.frytea.com", + password: Rails.application.credentials.smtp.password, + ssl: true, + authentication: "plain", + enable_starttls_auto: true, + open_timeout: 5, + read_timeout: 5 } # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. # config.action_mailer.smtp_settings = { diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index e150d16..c033f79 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -194,24 +194,24 @@ Devise.setup do |config| # Defines which strategy will be used to lock an account. # :failed_attempts = Locks an account after a number of failed attempts to sign in. # :none = No lock strategy. You should handle locking by yourself. - # config.lock_strategy = :failed_attempts + config.lock_strategy = :failed_attempts # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [:email] + config.unlock_keys = [:email] # Defines which strategy will be used to unlock an account. # :email = Sends an unlock link to the user email # :time = Re-enables login after a certain amount of time (see :unlock_in below) # :both = Enables both strategies # :none = No unlock strategy. You should handle unlocking by yourself. - # config.unlock_strategy = :both + config.unlock_strategy = :both # Number of authentication tries before locking an account if lock_strategy # is failed attempts. - # config.maximum_attempts = 20 + config.maximum_attempts = 5 # Time interval to unlock the account if :time is enabled as unlock_strategy. - # config.unlock_in = 1.hour + config.unlock_in = 24.hour # Warn on the last attempt before the account is locked. # config.last_attempt_warning = true