Add import-maps and turbo with some devise views

This commit is contained in:
Eugene Burmakin 2023-10-21 12:52:50 +02:00
parent 682a388f0e
commit c4e00dcf8b
26 changed files with 342 additions and 2 deletions

View file

@ -16,6 +16,7 @@ gem 'stimulus-rails'
gem 'tailwindcss-rails'
gem 'turbo-rails'
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
gem "importmap-rails", "~> 1.2"
group :development, :test do
gem 'debug', platforms: %i[mri mingw x64_mingw]
@ -33,3 +34,6 @@ group :development do
gem 'foreman'
gem 'rubocop-rails', require: false
end
# Use Redis for Action Cable
gem "redis", "~> 4.0"

View file

@ -110,6 +110,9 @@ GEM
activesupport (>= 6.1)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
importmap-rails (1.2.1)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
io-console (0.6.0)
irb (1.8.3)
rdoc
@ -143,6 +146,8 @@ GEM
racc (~> 1.4)
nokogiri (1.15.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-linux)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.23.0)
parser (3.2.2.4)
@ -197,6 +202,7 @@ GEM
rake (13.0.6)
rdoc (6.5.0)
psych (>= 4.0.0)
redis (4.8.1)
regexp_parser (2.8.2)
reline (0.3.9)
io-console (~> 0.5)
@ -265,6 +271,8 @@ GEM
railties (>= 6.0.0)
tailwindcss-rails (2.0.31-arm64-darwin)
railties (>= 6.0.0)
tailwindcss-rails (2.0.31-x86_64-linux)
railties (>= 6.0.0)
thor (1.3.0)
timeout (0.4.0)
turbo-rails (1.5.0)
@ -283,9 +291,11 @@ GEM
zeitwerk (2.6.12)
PLATFORMS
aarch64-linux
aarch64-linux-musl
arm64-darwin-21
arm64-darwin-22
x86_64-linux
DEPENDENCIES
bootsnap
@ -294,10 +304,12 @@ DEPENDENCIES
factory_bot_rails
ffaker (= 2.20.0)
foreman
importmap-rails (~> 1.2)
pg (~> 1.1)
puma (~> 6.4)
pundit (~> 2.2)
rails (= 7.1.1)
redis (~> 4.0)
rspec-rails (~> 5.1.0)
rubocop-rails
shoulda-matchers (~> 5.1)

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,5 @@
//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../builds
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js

View file

@ -0,0 +1,4 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@rails/actioncable"
import "@hotwired/turbo-rails"

View file

@ -0,0 +1,16 @@
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>
<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>

View file

@ -0,0 +1,5 @@
<p>Welcome <%= @email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>

View file

@ -0,0 +1,7 @@
<p>Hello <%= @email %>!</p>
<% if @resource.try(:unconfirmed_email?) %>
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
<% else %>
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
<% end %>

View file

@ -0,0 +1,3 @@
<p>Hello <%= @resource.email %>!</p>
<p>We're contacting you to notify you that your password has been changed.</p>

View file

@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View file

@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>

View file

@ -0,0 +1,25 @@
<h2>Change your password</h2>
<%= 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 %>
<div class="field">
<%= f.label :password, "New password" %><br />
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>
<%= render "devise/shared/links" %>

View file

@ -0,0 +1,16 @@
<h2>Forgot your password?</h2>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>

View file

@ -0,0 +1,61 @@
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full">
<div class="text-center lg:text-left">
<h1 class="text-5xl font-bold">Edit your account!</h1>
<p class="py-6">And change this text!</p>
</div>
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body', html: { method: :put }) do |f| %>
<div class="form-control">
<%= f.label :email, class: 'label' do %>
<span class="label-text">Email</span>
<% end %>
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'input input-bordered' %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="form-control mt-5">
<%= f.label :password, class: 'label' do %>
<span class="label-text">Password <i>(leave blank if you don't want to change it)</i></span>
<% end %>
<% if @minimum_password_length %>
<em class='text-xs'>(<%= @minimum_password_length %> characters minimum)</em>
<% end %>
<%= f.password_field :password, autocomplete: "new-password", class: 'input input-bordered' %>
</div>
<div class="form-control mt-5">
<%= f.label :password_confirmation, class: 'label' do %>
<span class="label-text">Password confirmation</span>
<% end %>
<% if @minimum_password_length %>
<em class='text-xs'>(<%= @minimum_password_length %> characters minimum)</em>
<% end %>
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'input input-bordered' %>
</div>
<div class="form-control mt-5">
<%= f.label :current_password, class: 'label' do %>
<span class="label-text">Current password</span>
<% end %>
<% if @minimum_password_length %>
<em class='text-xs'>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<i class='text-xs'>(we need your current password to confirm your changes)</i>
<%= f.password_field :current_password, autocomplete: "current-password", class: 'input input-bordered' %>
</div>
<div class="form-control mt-6">
<%= f.submit "Update", class: 'btn btn-primary' %>
</div>
<%= render "devise/shared/links" %>
<% end %>
<p class='mt-3'>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn' %></p>
</div>
</div>
</div>

View file

@ -0,0 +1,44 @@
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full">
<div class="text-center lg:text-left">
<h1 class="text-5xl font-bold">Register now!</h1>
<p class="py-6">And change this text!</p>
</div>
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body ') do |f| %>
<div class="form-control">
<%= f.label :email, class: 'label' do %>
<span class="label-text">Email</span>
<% end %>
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'input input-bordered' %>
</div>
<div class="form-control">
<%= f.label :password, class: 'label' do %>
<span class="label-text">Password</span>
<% end %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password", class: 'input input-bordered' %>
</div>
<div class="form-control">
<%= f.label :password_confirmation, class: 'label' do %>
<span class="label-text">Password</span>
<% end %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'input input-bordered' %>
</div>
<div class="form-control mt-6">
<%= f.submit "Sign up", class: 'btn btn-primary' %>
</div>
<%= render "devise/shared/links" %>
<% end %>
</div>
</div>
</div>

View file

@ -0,0 +1,37 @@
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full">
<div class="text-center lg:text-left">
<h1 class="text-5xl font-bold">Login now!</h1>
<p class="py-6">And change this text!</p>
</div>
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
<%= form_for(resource, as: resource_name, url: session_path(resource_name), class: 'form-body ') do |f| %>
<div class="form-control">
<%= f.label :email, class: 'label' do %>
<span class="label-text">Email</span>
<% end %>
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'input input-bordered' %>
</div>
<div class="form-control">
<%= f.label :password, class: 'label' do %>
<span class="label-text">Password</span>
<% end %>
<%= f.password_field :password, autocomplete: "current-password", class: 'input input-bordered' %>
<% if devise_mapping.rememberable? %>
<div class="form-control">
<label class="label cursor-pointer">
<span class="label-text">Remember me</span>
<%= f.check_box :remember_me, class: 'checkbox checkbox-sm' %>
</label>
</div>
<% end %>
</div>
<div class="form-control mt-6">
<%= f.submit "Log in", class: 'btn btn-primary' %>
</div>
<%= render "devise/shared/links" %>
<% end %>
</div>
</div>
</div>

View file

@ -0,0 +1,15 @@
<% if resource.errors.any? %>
<div id="error_explanation" data-turbo-cache="false">
<h2>
<%= I18n.t("errors.messages.not_saved",
count: resource.errors.count,
resource: resource.class.model_name.human.downcase)
%>
</h2>
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>

View file

@ -0,0 +1,25 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Log in", new_session_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% 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) %><br />
<% end %>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
<% end %>
<% end %>

View file

@ -0,0 +1,16 @@
<h2>Resend unlock instructions</h2>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="actions">
<%= f.submit "Resend unlock instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>

View file

@ -10,6 +10,7 @@
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body>

4
bin/importmap Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
require_relative "../config/application"
require "importmap/commands"

View file

@ -1,5 +1,6 @@
development:
adapter: async
adapter: redis
url: redis://localhost:6379/1
test:
adapter: test

8
config/importmap.rb Normal file
View file

@ -0,0 +1,8 @@
# Pin npm packages by running ./bin/importmap
pin_all_from "app/javascript/channels", under: "channels"
pin "application", preload: true
pin "@rails/actioncable", to: "actioncable.esm.js"
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true

View file

@ -1,5 +1,6 @@
{
"dependencies": {
"@hotwired/turbo-rails": "^7.3.0",
"daisyui": "^2.13.2"
}
}

0
vendor/javascript/.keep vendored Normal file
View file

View file

@ -7,6 +7,19 @@
resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
"@hotwired/turbo-rails@^7.3.0":
version "7.3.0"
resolved "https://registry.npmjs.org/@hotwired/turbo-rails/-/turbo-rails-7.3.0.tgz#422c21752509f3edcd6c7b2725bbe9e157815f51"
integrity sha512-fvhO64vp/a2UVQ3jue9WTc2JisMv9XilIC7ViZmXAREVwiQ2S4UC7Go8f9A1j4Xu7DBI6SbFdqILk5ImqVoqyA==
dependencies:
"@hotwired/turbo" "^7.3.0"
"@rails/actioncable" "^7.0"
"@hotwired/turbo@^7.3.0":
version "7.3.0"
resolved "https://registry.npmjs.org/@hotwired/turbo/-/turbo-7.3.0.tgz#2226000fff1aabda9fd9587474565c9929dbf15d"
integrity sha512-Dcu+NaSvHLT7EjrDrkEmH4qET2ZJZ5IcCWmNXxNQTBwlnE5tBZfN6WxZ842n5cHV52DH/AKNirbPBtcEXDLW4g==
"@jridgewell/gen-mapping@^0.3.2":
version "0.3.3"
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
@ -60,6 +73,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@rails/actioncable@^7.0":
version "7.1.1"
resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.1.tgz#e8c49769d41f35a4473133c259cc98adc04dddf8"
integrity sha512-ZRJ9rdwFQQjRbtgJnweY0/4UQyxN6ojEGRdib0JkjnuIciv+4ok/aAeZmBJqNreTMaBqS0eHyA9hCArwN58opg==
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"