kaze 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kaze/commands/install_command.rb +25 -13
- data/lib/kaze/commands/installs_hotwire_stack.rb +11 -8
- data/lib/kaze/commands/installs_inertia_stacks.rb +34 -24
- data/lib/kaze/commands/version_command.rb +6 -0
- data/lib/kaze/version.rb +1 -1
- data/lib/kaze.rb +1 -3
- data/stubs/default/app/forms/auth/login_form.rb +2 -8
- data/stubs/default/app/forms/auth/new_password_form.rb +1 -1
- data/stubs/default/app/forms/update_profile_information_form.rb +1 -1
- data/stubs/default/app/mailers/application_mailer.rb +4 -4
- data/stubs/default/app/mailers/user_mailer.rb +1 -1
- data/stubs/default/app/models/auth.rb +57 -0
- data/stubs/default/app/models/current.rb +1 -1
- data/stubs/default/app/validators/current_password_validator.rb +1 -1
- data/stubs/default/app/validators/email_validator.rb +1 -1
- data/stubs/default/app/validators/lowercase_validator.rb +2 -2
- data/stubs/default/app/views/layouts/mailer.html.erb +367 -372
- data/stubs/default/app/views/layouts/mailer.text.erb +1 -4
- data/stubs/default/app/views/user_mailer/reset_password.html.erb +21 -26
- data/stubs/default/config/routes.rb +16 -16
- data/stubs/default/db/migrate/20240101000001_create_delayed_jobs.rb +1 -1
- data/stubs/default/test/factories/users.rb +7 -0
- data/stubs/default/test/integration/auth/authentication_test.rb +43 -0
- data/stubs/default/test/integration/auth/password_reset_test.rb +41 -0
- data/stubs/default/test/integration/auth/registration_test.rb +21 -0
- data/stubs/default/test/integration/password_update_test.rb +28 -0
- data/stubs/default/test/integration/profile_test.rb +51 -0
- data/stubs/default/test/test_helper.rb +38 -0
- data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
- data/stubs/hotwire/app/components/dropdown_component.html.erb +17 -18
- data/stubs/hotwire/app/components/dropdown_component.rb +7 -7
- data/stubs/hotwire/app/components/modal_component.html.erb +55 -59
- data/stubs/hotwire/app/components/modal_component.rb +6 -6
- data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
- data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
- data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
- data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +12 -9
- data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/hotwire/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/hotwire/app/controllers/password_controller.rb +3 -3
- data/stubs/hotwire/app/controllers/profile_controller.rb +11 -9
- data/stubs/hotwire/app/controllers/welcome_controller.rb +1 -1
- data/stubs/hotwire/app/javascript/application.js +3 -3
- data/stubs/hotwire/app/views/auth/forgot_password.html.erb +12 -17
- data/stubs/hotwire/app/views/auth/login.html.erb +0 -9
- data/stubs/hotwire/app/views/auth/register.html.erb +0 -13
- data/stubs/hotwire/app/views/auth/reset_password.html.erb +0 -7
- data/stubs/hotwire/app/views/dashboard/index.html.erb +9 -10
- data/stubs/hotwire/app/views/layouts/_navigation.html.erb +77 -87
- data/stubs/hotwire/app/views/layouts/application.html.erb +0 -9
- data/stubs/hotwire/app/views/layouts/guest.html.erb +0 -6
- data/stubs/hotwire/app/views/profile/edit.html.erb +19 -22
- data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +32 -42
- data/stubs/hotwire/app/views/profile/partials/_update_password_form.html.erb +42 -55
- data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +36 -46
- data/stubs/hotwire/app/views/welcome/index.html.erb +34 -46
- data/stubs/hotwire/config/importmap.rb +3 -3
- data/stubs/hotwire/config/tailwind.config.js +2 -2
- data/stubs/inertia-common/app/controllers/application_controller.rb +1 -0
- data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +11 -8
- data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +1 -1
- data/stubs/inertia-common/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/inertia-common/app/controllers/concerns/verify_csrf_token.rb +4 -4
- data/stubs/inertia-common/app/controllers/dashboard_controller.rb +1 -1
- data/stubs/inertia-common/app/controllers/password_controller.rb +1 -1
- data/stubs/inertia-common/app/controllers/profile_controller.rb +7 -5
- data/stubs/inertia-common/app/controllers/welcome_controller.rb +2 -2
- data/stubs/inertia-common/bin/vite +6 -6
- data/stubs/inertia-common/test/integration/password_update_test.rb +28 -0
- data/stubs/inertia-common/test/integration/profile_test.rb +51 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +13 -9
- data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +15 -12
- data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +119 -87
- data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +14 -7
- data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +18 -7
- data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +60 -60
- data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +21 -16
- data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +19 -14
- data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +22 -16
- data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +35 -24
- data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +157 -117
- data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +15 -15
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -49
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +90 -82
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -115
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +63 -60
- data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +23 -17
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +31 -27
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +109 -99
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +121 -113
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +76 -69
- data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +87 -63
- data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +32 -25
- data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-react-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-react-ts/vite.config.ts +2 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +10 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +18 -18
- data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +60 -57
- data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +9 -9
- data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +7 -7
- data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +6 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +84 -74
- data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +168 -136
- data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +15 -13
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +56 -49
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +78 -72
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +101 -97
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +71 -68
- data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -14
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +34 -30
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +87 -83
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +105 -98
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +69 -59
- data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +74 -47
- data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-vue-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-vue-ts/vite.config.ts +2 -5
- metadata +19 -6
- data/stubs/hotwire/bin/vite +0 -27
- data/stubs/inertia-common/Procfile.dev +0 -3
- /data/stubs/{hotwire → default}/Procfile.dev +0 -0
- /data/stubs/hotwire/app/javascript/{alpinejs.js → alpinejs.stub} +0 -0
@@ -3,27 +3,19 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
-
|
7
6
|
<title><%= content_for(:title) || "Rails" %></title>
|
8
|
-
|
9
7
|
<%= csrf_meta_tags %>
|
10
8
|
<%= csp_meta_tag %>
|
11
|
-
|
12
9
|
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
13
|
-
|
14
10
|
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
15
11
|
<%= javascript_importmap_tags %>
|
16
|
-
|
17
12
|
<%= hotwire_livereload_tags if Rails.env.development? %>
|
18
13
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
19
|
-
|
20
14
|
<%= yield :head %>
|
21
15
|
</head>
|
22
|
-
|
23
16
|
<body class="font-sans antialiased">
|
24
17
|
<div class="min-h-screen bg-gray-100">
|
25
18
|
<%= render "layouts/navigation" %>
|
26
|
-
|
27
19
|
<!-- Page Heading -->
|
28
20
|
<% if content_for?(:header) %>
|
29
21
|
<header class="bg-white dark:bg-gray-800 shadow">
|
@@ -32,7 +24,6 @@
|
|
32
24
|
</div>
|
33
25
|
</header>
|
34
26
|
<% end %>
|
35
|
-
|
36
27
|
<!-- Page Content -->
|
37
28
|
<main>
|
38
29
|
<%= yield %>
|
@@ -3,17 +3,12 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
-
|
7
6
|
<title><%= content_for(:title) || "Rails" %></title>
|
8
|
-
|
9
7
|
<%= csrf_meta_tags %>
|
10
8
|
<%= csp_meta_tag %>
|
11
|
-
|
12
9
|
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
13
|
-
|
14
10
|
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
15
11
|
<%= javascript_importmap_tags %>
|
16
|
-
|
17
12
|
<%= hotwire_livereload_tags if Rails.env.development? %>
|
18
13
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
19
14
|
</head>
|
@@ -24,7 +19,6 @@
|
|
24
19
|
<%= render(ApplicationLogoComponent.new({ class: "w-20 h-20 fill-current text-gray-500" })) %>
|
25
20
|
</a>
|
26
21
|
</div>
|
27
|
-
|
28
22
|
<div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg">
|
29
23
|
<%= yield %>
|
30
24
|
</div>
|
@@ -1,27 +1,24 @@
|
|
1
1
|
<% content_for(:header) do %>
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
3
|
+
Profile
|
4
|
+
</h2>
|
5
5
|
<% end %>
|
6
|
-
|
7
6
|
<div class="py-12">
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
</div>
|
14
|
-
|
15
|
-
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
16
|
-
<div class="max-w-xl">
|
17
|
-
<%= render "profile/partials/update_password_form" %>
|
18
|
-
</div>
|
19
|
-
</div>
|
20
|
-
|
21
|
-
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
22
|
-
<div class="max-w-xl">
|
23
|
-
<%= render "profile/partials/delete_user_form" %>
|
24
|
-
</div>
|
25
|
-
</div>
|
7
|
+
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
|
8
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
9
|
+
<div class="max-w-xl">
|
10
|
+
<%= render "profile/partials/update_profile_information_form" %>
|
11
|
+
</div>
|
26
12
|
</div>
|
13
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
14
|
+
<div class="max-w-xl">
|
15
|
+
<%= render "profile/partials/update_password_form" %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
19
|
+
<div class="max-w-xl">
|
20
|
+
<%= render "profile/partials/delete_user_form" %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
</div>
|
27
24
|
</div>
|
@@ -1,48 +1,38 @@
|
|
1
1
|
<section class="space-y-6">
|
2
|
-
|
2
|
+
<header>
|
3
|
+
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
4
|
+
Delete Account
|
5
|
+
</h2>
|
6
|
+
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
7
|
+
Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.
|
8
|
+
</p>
|
9
|
+
</header>
|
10
|
+
<%= render(DangerButtonComponent.new({"x-data": "", "x-on:click.prevent": "$dispatch('open-modal', 'confirm-user-deletion')"})) do %>
|
11
|
+
Delete Account
|
12
|
+
<% end %>
|
13
|
+
<%= render(ModalComponent.new({ :name => "confirm-user-deletion", :show => @delete_user_form.error_messages.has_key?(:password), :focusable => true })) do %>
|
14
|
+
<turbo-frame id="delete_user_form">
|
15
|
+
<%= form_with model: @delete_user_form, url: profile_destroy_path, method: "delete", class: "p-6" do %>
|
3
16
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
4
|
-
|
17
|
+
Are you sure you want to delete your account?
|
5
18
|
</h2>
|
6
|
-
|
7
19
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
8
|
-
|
20
|
+
Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.
|
9
21
|
</p>
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
<div class="mt-6">
|
28
|
-
<%= render(InputLabelComponent.new({ for: "password", value: "Password", class: "sr-only" })) %>
|
29
|
-
|
30
|
-
<%= render(TextInputComponent.new({ id: "password", class: "mt-1 block w-3/4", type: "password", name: "password", placeholder: "Password" })) %>
|
31
|
-
|
32
|
-
<%= render(InputErrorComponent.new({ class: "mt-2", message: @delete_user_form.error_messages[:password] })) %>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<div class="mt-6 flex justify-end">
|
36
|
-
<%= render(SecondaryButtonComponent.new({ "x-on:click": "$dispatch('close')" })) do %>
|
37
|
-
Cancel
|
38
|
-
<% end %>
|
39
|
-
|
40
|
-
<%= render(DangerButtonComponent.new({ class: "ms-3" })) do %>
|
41
|
-
Delete Account
|
42
|
-
<% end %>
|
43
|
-
</div>
|
44
|
-
<% end %>
|
45
|
-
</turbo-frame>
|
46
|
-
<% end %>
|
22
|
+
<div class="mt-6">
|
23
|
+
<%= render(InputLabelComponent.new({ for: "password", value: "Password", class: "sr-only" })) %>
|
24
|
+
<%= render(TextInputComponent.new({ id: "password", class: "mt-1 block w-3/4", type: "password", name: "password", placeholder: "Password" })) %>
|
25
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @delete_user_form.error_messages[:password] })) %>
|
26
|
+
</div>
|
27
|
+
<div class="mt-6 flex justify-end">
|
28
|
+
<%= render(SecondaryButtonComponent.new({ "x-on:click": "$dispatch('close')" })) do %>
|
29
|
+
Cancel
|
30
|
+
<% end %>
|
31
|
+
<%= render(DangerButtonComponent.new({ class: "ms-3" })) do %>
|
32
|
+
Delete Account
|
33
|
+
<% end %>
|
34
|
+
</div>
|
35
|
+
<% end %>
|
36
|
+
</turbo-frame>
|
37
|
+
<% end %>
|
47
38
|
</section>
|
48
|
-
|
@@ -1,58 +1,45 @@
|
|
1
1
|
<turbo-frame id="update_password_form">
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
<div class="mt-4">
|
34
|
-
<%= render(InputLabelComponent.new({ for: "update_password_password_confirmation", value: "Confirm Password" })) %>
|
35
|
-
|
36
|
-
<%= render(TextInputComponent.new({ id: "update_password_password_confirmation", class: "block mt-1 w-full", type: "password", name: "password_confirmation", autocomplete: "new-password" })) %>
|
37
|
-
|
38
|
-
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_password_form.error_messages[:password_confirmation] })) %>
|
39
|
-
</div>
|
40
|
-
|
41
|
-
<div class="flex items-center gap-4">
|
42
|
-
<%= render(PrimaryButtonComponent.new) do %>
|
43
|
-
Save
|
44
|
-
<% end %>
|
45
|
-
|
46
|
-
<% if flash[:status] == "password-updated" %>
|
47
|
-
<p
|
48
|
-
x-data="{ show: true }"
|
49
|
-
x-show="show"
|
50
|
-
x-transition
|
51
|
-
x-init="setTimeout(() => show = false, 2000)"
|
52
|
-
class="text-sm text-gray-600 dark:text-gray-400"
|
53
|
-
>Saved.</p>
|
54
|
-
<% end %>
|
55
|
-
</div>
|
2
|
+
<section>
|
3
|
+
<header>
|
4
|
+
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
5
|
+
Update Password
|
6
|
+
</h2>
|
7
|
+
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
8
|
+
Ensure your account is using a long, random password to stay secure.
|
9
|
+
</p>
|
10
|
+
</header>
|
11
|
+
<%= form_with model: @update_password_form, url: password_update_path, method: "put", class: "mt-6 space-y-6" do |update_password_form| %>
|
12
|
+
<!-- Current Password -->
|
13
|
+
<div>
|
14
|
+
<%= render(InputLabelComponent.new({ for: "update_password_current_password", value: "Current Password" })) %>
|
15
|
+
<%= render(TextInputComponent.new({ id: "update_password_current_password", class: "block mt-1 w-full", type: "password", name: "current_password", autocomplete: "current-password" })) %>
|
16
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_password_form.error_messages[:current_password] })) %>
|
17
|
+
</div>
|
18
|
+
<!-- New Password -->
|
19
|
+
<div>
|
20
|
+
<%= render(InputLabelComponent.new({ for: "update_password_password", value: "New Password" })) %>
|
21
|
+
<%= render(TextInputComponent.new({ id: "update_password_password", class: "block mt-1 w-full", type: "password", name: "password", autocomplete: "new-password" })) %>
|
22
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_password_form.error_messages[:password] })) %>
|
23
|
+
</div>
|
24
|
+
<!-- Confirm Password -->
|
25
|
+
<div class="mt-4">
|
26
|
+
<%= render(InputLabelComponent.new({ for: "update_password_password_confirmation", value: "Confirm Password" })) %>
|
27
|
+
<%= render(TextInputComponent.new({ id: "update_password_password_confirmation", class: "block mt-1 w-full", type: "password", name: "password_confirmation", autocomplete: "new-password" })) %>
|
28
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_password_form.error_messages[:password_confirmation] })) %>
|
29
|
+
</div>
|
30
|
+
<div class="flex items-center gap-4">
|
31
|
+
<%= render(PrimaryButtonComponent.new) do %>
|
32
|
+
Save
|
56
33
|
<% end %>
|
57
|
-
|
34
|
+
<% if flash[:status] == "password-updated" %>
|
35
|
+
<p
|
36
|
+
x-data="{ show: true }"
|
37
|
+
x-show="show"
|
38
|
+
x-transition
|
39
|
+
x-init="setTimeout(() => show = false, 2000)"
|
40
|
+
class="text-sm text-gray-600 dark:text-gray-400">Saved.</p>
|
41
|
+
<% end %>
|
42
|
+
</div>
|
43
|
+
<% end %>
|
44
|
+
</section>
|
58
45
|
</turbo-frame>
|
@@ -1,49 +1,39 @@
|
|
1
1
|
<turbo-frame id="update_profile_information_form">
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
<%= render(TextInputComponent.new({ id: "email", class: "block mt-1 w-full", type: "email", name: "email", value: @update_profile_information_form.email, required: true, autocomplete: "username" })) %>
|
28
|
-
|
29
|
-
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_profile_information_form.error_messages[:email] })) %>
|
30
|
-
</div>
|
31
|
-
|
32
|
-
<div class="flex items-center gap-4">
|
33
|
-
<%= render(PrimaryButtonComponent.new) do %>
|
34
|
-
Save
|
35
|
-
<% end %>
|
36
|
-
|
37
|
-
<% if flash[:status] == "profile-updated" %>
|
38
|
-
<p
|
39
|
-
x-data="{ show: true }"
|
40
|
-
x-show="show"
|
41
|
-
x-transition
|
42
|
-
x-init="setTimeout(() => show = false, 2000)"
|
43
|
-
class="text-sm text-gray-600 dark:text-gray-400"
|
44
|
-
>Saved.</p>
|
45
|
-
<% end %>
|
46
|
-
</div>
|
2
|
+
<section>
|
3
|
+
<header>
|
4
|
+
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
5
|
+
Profile Information
|
6
|
+
</h2>
|
7
|
+
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
8
|
+
Update your account's profile information and email address.
|
9
|
+
</p>
|
10
|
+
</header>
|
11
|
+
<%= form_with model: @update_profile_information_form, url: profile_update_path, method: "patch", class: "mt-6 space-y-6" do %>
|
12
|
+
<!-- Name -->
|
13
|
+
<div>
|
14
|
+
<%= render(InputLabelComponent.new({ for: "name", value: "Name" })) %>
|
15
|
+
<%= render(TextInputComponent.new({ id: "name", class: "block mt-1 w-full", type: "text", name: "name", value: @update_profile_information_form.name, required: true, autofocus: true, autocomplete: "name" })) %>
|
16
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_profile_information_form.error_messages[:name] })) %>
|
17
|
+
</div>
|
18
|
+
<!-- Email Address -->
|
19
|
+
<div class="mt-4">
|
20
|
+
<%= render(InputLabelComponent.new({ for: "email", value: "Email" })) %>
|
21
|
+
<%= render(TextInputComponent.new({ id: "email", class: "block mt-1 w-full", type: "email", name: "email", value: @update_profile_information_form.email, required: true, autocomplete: "username" })) %>
|
22
|
+
<%= render(InputErrorComponent.new({ class: "mt-2", message: @update_profile_information_form.error_messages[:email] })) %>
|
23
|
+
</div>
|
24
|
+
<div class="flex items-center gap-4">
|
25
|
+
<%= render(PrimaryButtonComponent.new) do %>
|
26
|
+
Save
|
47
27
|
<% end %>
|
48
|
-
|
28
|
+
<% if flash[:status] == "profile-updated" %>
|
29
|
+
<p
|
30
|
+
x-data="{ show: true }"
|
31
|
+
x-show="show"
|
32
|
+
x-transition
|
33
|
+
x-init="setTimeout(() => show = false, 2000)"
|
34
|
+
class="text-sm text-gray-600 dark:text-gray-400">Saved.</p>
|
35
|
+
<% end %>
|
36
|
+
</div>
|
37
|
+
<% end %>
|
38
|
+
</section>
|
49
39
|
</turbo-frame>
|
@@ -4,65 +4,53 @@
|
|
4
4
|
<meta charset="utf-8">
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
6
|
<meta name="turbo-visit-control" content="reload">
|
7
|
-
|
8
7
|
<title><%= content_for(:title) || "Rails" %></title>
|
9
|
-
|
10
8
|
<%= csrf_meta_tags %>
|
11
9
|
<%= csp_meta_tag %>
|
12
|
-
|
13
10
|
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
14
|
-
|
15
11
|
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
16
12
|
<%= javascript_importmap_tags %>
|
17
|
-
|
18
13
|
<%= hotwire_livereload_tags if Rails.env.development? %>
|
19
14
|
<%= turbo_refreshes_with method: :morph, scroll: :preserve %>
|
20
15
|
</head>
|
21
|
-
|
22
16
|
<body class="font-sans antialiased">
|
23
17
|
<div
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
<
|
28
|
-
|
29
|
-
<% if Current.user %>
|
30
|
-
<a
|
31
|
-
href="<%= dashboard_url %>"
|
32
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white"
|
33
|
-
v-if="$page.props.auth.user"
|
34
|
-
>
|
35
|
-
Dashboard
|
36
|
-
</a>
|
37
|
-
<% else %>
|
38
|
-
<a
|
39
|
-
href="<%= login_url %>"
|
40
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white"
|
41
|
-
>
|
42
|
-
Log in
|
43
|
-
</a>
|
44
|
-
<a
|
45
|
-
href="<%= register_url %>"
|
46
|
-
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white"
|
47
|
-
>
|
48
|
-
Register
|
49
|
-
</a>
|
50
|
-
<% end %>
|
51
|
-
</div>
|
52
|
-
</header>
|
53
|
-
<nav style="font-size: 0;height: 20vw;line-height: 0;max-height: 280px;max-width: 280px;min-height: 86px;min-width: 86px;width: 20vw;">
|
18
|
+
class="flex flex-col items-center justify-center bg-[#F0E7E9] bg-center bg-cover text-[#261B23] not-italic font-normal leading-tight min-h-screen text-center"
|
19
|
+
style="background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMjQiIHZpZXdCb3g9IjAgMCAxNDQwIDEwMjQiIHdpZHRoPSIxNDQwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNDQwIDUxMC4wMDA2NDh2LTUxMC4wMDA2NDhoLTE0NDB2Mzg0LjAwMDY0OGM0MTcuMzExOTM5IDEzMS4xNDIxNzkgODkxIDE3MS41MTMgMTQ0MCAxMjZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+);font-family: Sans-Serif;font-size: calc(0.9em + 0.5vw);">
|
20
|
+
<header class="absolute top-0 right-0 grid grid-cols-2 items-center gap-2 py-10 lg:grid-cols-3">
|
21
|
+
<div class="-mx-3 flex flex-1 justify-end">
|
22
|
+
<% if Current.auth.check? %>
|
54
23
|
<a
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
24
|
+
href="<%= dashboard_url %>"
|
25
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white"
|
26
|
+
v-if="$page.props.auth.user">
|
27
|
+
Dashboard
|
59
28
|
</a>
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
29
|
+
<% else %>
|
30
|
+
<a
|
31
|
+
href="<%= login_url %>"
|
32
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white">
|
33
|
+
Log in
|
34
|
+
</a>
|
35
|
+
<a
|
36
|
+
href="<%= register_url %>"
|
37
|
+
class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20] dark:text-white dark:hover:text-white/80 dark:focus-visible:ring-white">
|
38
|
+
Register
|
39
|
+
</a>
|
40
|
+
<% end %>
|
41
|
+
</div>
|
42
|
+
</header>
|
43
|
+
<nav style="font-size: 0;height: 20vw;line-height: 0;max-height: 280px;max-width: 280px;min-height: 86px;min-width: 86px;width: 20vw;">
|
44
|
+
<a
|
45
|
+
class="bg-[#D30001] hover:bg-[#261B23] flex rounded-full" href="https://rubyonrails.org" target="_blank"
|
46
|
+
style="transition: background 0.25s cubic-bezier(0.33, 1, 0.68, 1);filter: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08));">
|
47
|
+
<img class="h-auto max-w-full w-full cursor-pointer" alt="" src="data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjExMiIgdmlld0JveD0iMCAwIDExMiAxMTIiIHdpZHRoPSIxMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTEwMC4wODIzNTcgNDguOTk5NTQwM3Y0LjExMzUwMzRoLTcuMzAwMzM4OHYxLjg5ODU0aDMuNjg0MDcxN2MxLjk3MjUwOTEgMCA0LjA3MjUzNDEgMS40NjY0MzExIDQuMTk3OTk3MSAzLjk2NjUxMjRsLjAwNTkxMy4yMzczOTc3djEuNTgyMTE2N2MtLjA4NzgyNCAzLjAwNzk1OS0yLjU0MzEyMTEgNC4xMzkwMDE4LTQuMDcxNTM4OSA0LjIwMTE3NzNsLS4xMzIzNzEyLjAwMjczMjhoLTcuMzkwNzQ1MXYtNC4wOTA5MDE4bDcuNDgxMTUxOC0uMDIyNjAxNnYtMS45ODg5NDY3aC0zLjQ4MDY1NjdjLTEuNzc1MjU4MyAwLTQuMDgxODMyMS0xLjMzODkxNTMtNC4yMTk5OTQyLTMuOTU0OTIwMWwtLjAwNjUxNzYtLjI0ODk5di0xLjQyMzkwNWMwLTIuNjk4MjQwMiAyLjI3ODIxMjktNC4xODI4NTMgNC4wNjU0NjQtNC4yNjc4NDkxbC4xNjEwNDc4LS4wMDM4NjZ6bS0xOC42OTE1NzkgMHYxMS44NjU4NzUyaDYuMTcwMjU1MXY0LjEzNjEwNTFoLTEwLjczNTc5MTl2LTE2LjAwMTk4MDN6bS02LjQ0MTQ3NTEgMHYxNi4wMDE5ODAzaC00LjU4ODEzODV2LTE2LjAwMTk4MDN6bS0xNS4yMTA5MjIgMGg0LjQwNzMyNTFsLjE4NzcyNC4wMDY2ODEyYy4wMzM4NjA5LjAwMjI3MzUuMDY4OTQ1Ny4wMDUxNDk5LjEwNTE2MDEuMDA4NjY0M2wuMjMwMDg3NS4wMjkwMTc4YzEuMjkxMzgyOS4xOTg1NDc2IDMuNTQ2MzgxNiAxLjEyMTM4MTYgMy42NzUxNzA4IDMuOTA2ODU4N2wuMDA1NzY3Ny4yNTI2ODgxdjExLjc5ODA3MDJoLTQuMjcxNzE1MXYtMi44MjUyMDg0aC00LjEzNjEwNTF2Mi44MjUyMDg0aC00LjQwNzMyNTF2LTExLjc5ODA3MDJjMC0xLjMxODQzMDYgMS4wMDQwODI2LTQuMDQ2ODQ5NSAzLjk0Njg5OS00LjE5NzQxMXptLTE5LjczOTg1MTktLjAwMjc1ODEgOC41ODAxODU3LjAwMDU3NDkuMjM4OTIzNC4wMzY3NDYyLjE0Nzk0NTkuMDI5NDE3LjI3NDExNjEuMDY1MzU4Mi4yMTI1MTk4LjA1OTkwNjguMjMyMzIyNS4wNzQ3MTgyYy4wNDAxNzkzLjAxMzc3MDQuMDgxMDQwMi4wMjgyMjAxLjEyMjUxMS4wNDMzODA0bC4yNTU1NjkxLjA5OTczNzYuMjY2NzYxOC4xMTgyODUyYzEuMzU2MDUxNS42NDAyODY2IDMuMDAyNjg1NSAyLjAzMjE1ODMgMy4wMDI2ODU1IDUuMDE2Mjk0IDAgMy4xODMwNzgxLTEuNTQ2NTI0MSA0LjUwMTQ4OTktMi42OTg4MzYyIDUuMDQyMDQ3N2wtLjIxMDk2NTEuMDkyNTA0NS0uMTk4ODgyOC4wNzU4NjU1LS4xODM5NTc3LjA2MDgxODYtLjE2NjE4OTguMDQ3MzYzNi0uMjA5NzUwOC4wNDkzMDAxLS4yNTk2NDkzLjA0MTgzNjMgNS4wMDU2ODk1IDUuMDUwNTgzNmgtNi4zNzQ5NTg5bC0zLjcyNjIwODMtMy44NjA4OTA2djMuODYwODkwNmgtNC4zMDk4MzE0em0yMi4wMDcwNjAzLTMuMDg2OTE5My40NDQ5OTE3LjQyMjY4MDctLjI0Mjk2OC4xNzc5ODgxLS4zNDgyMzMxLjI2OTMzNjUtLjE5OTg1NzMuMTYyOTIwNGMtNS4yMzk4OTY3LTMuODc0NTcxNS05LjY0NzY0NTQtNS40MjIxNDA5LTEzLjE5NzExOS01LjgxNTM1MzdsLS41MjU5ODA3LS4wNTA0NzA4Yy0xLjAzOTA3NDItLjA4NDIxMjYtMi4wMDA3ODYxLS4wNjk4MTAxLTIuODg0NDMwMi4wMTE1NDYybC0uNDM1MzEzMi4wNDYxMTExYy0uMDcxNDY2OC4wMDg1NjYyLS4xNDIzOTA3LjAxNzU2MDgtLjIxMjc3MTIuMDI2OTY1M2wtLjQxNTc1OTUuMDYxMjAwNS0uNDAyNjk5MS4wNzAxNjA3LS4zODk2MTk0LjA3ODI0MTUtLjM3NjUxOTguMDg1NDQyN2MtLjA2MTY2MDYuMDE0NzkxNy0uMTIyNzc0Ni4wMjk4NDY4LS4xODMzNDE1LjA0NTE0N2wtLjM1NjgzMzkuMDk0NTk1Ny0uMzQzNjg1NC4wOTk1OTgyLS4zMzA1MTc0LjEwMzcyMTMtLjMxNzMyOTcuMTA2OTY0OS0uMzA0MTIyNS4xMDkzMjktLjI5MDg5NTYuMTEwODEzNy0uNDExNTAwMi4xNjcwODAzLS41MDIxOTAyLjIxOTc2MTUtLjY1MzM3MzYuMzA4ODk1Ni0uNjEwMTA1LjMwMDU2NzVjLTQuNjk4ODg2NiAyLjYyMTk3ODgtNi44NTM5Mjk0IDYuODQ2MDcxMS03Ljc2ODIwMDIgMTAuODg2NjQ2M2wtLjEyMjMxMDEuNTc1NzgzOGMtLjAzODA1MDQuMTkxMzgzMy0uMDczNDI3OC4zODIxNTc2LS4xMDYyNzMyLjU3MjEzMDFsLS4wOTEwODA0LjU2NzMxOTYtLjA3NjczMTguNTYxMzUyMS0uMDYzMjI3NS41NTQyMjc3Yy0uMDA5NDU5NC4wOTE3MTM0LS4wMTgzOTE0LjE4MzA4MTctLjAyNjgxMzQuMjc0MDgwOGwtLjA0NDU1NC41NDEzNzIyLS4wMzMxNjAxLjUzMTM1NTZjLS4wMDQ2MjQyLjA4NzY2MDMtLjAwODgwODcuMTc0ODU1MS0uMDEyNTcxMy4yNjE1NjAybC0uMDE3NjUyNS41MTQxNjE4LS4wMDgzNjkzLjUwMTI1MzEuMDAwMDY5Ni40ODcxODc2LjAxNDA4MDYuNzAxODc3OS4wMjgzMTk1LjY2MzcyMjkuMDM5NzA4OS42MjE2NjM3LjA0ODI0OTIuNTc1Njk5OS4wNTM5NDAyLjUyNTgzMTcuMDc1ODQ4MS42MTY3ODc5LjA3NDE0NjIuNTExOTM3LjA4MDAwMDIuNDc4Mzc1Ni4wNjg1OTk1LjM1NDA4NjNoLTE3Ljg1NTMxN2wuMDU4NDktLjQ0MTcyNTMuMDQ2MzM2OC0uMjk1MTQ0OC4wNjMwMjA2LS4zNjQ3MjQyLjExMzI4MTktLjU4OTIwNjkuMTA5Mzc4Ny0uNTE1MDkwNy4xODIwMjY1LS43Nzg1MDg4LjE2NjEzNzYtLjY0ODY3NzIuMTI1OTIzMy0uNDYxNTk0My4yMTMwNDc0LS43MzM4MjI1LjE1ODk2NTUtLjUxNTUwNDIuMTczMTcyOC0uNTM1NDY5OS4xODc5NDYzLS41NTQ1MjI2LjIwMzI4NTctLjU3MjY2Mi4yMTkxOTEzLS41ODk4ODgzLjIzNTY2MjgtLjYwNjIwMTQuMjUyNzAwNC0uNjIxNjAxMmMuMDQzNTY4LS4xMDQ4MzI4LjA4Nzg2OTQtLjIxMDI2OTEuMTMyOTE2Mi0uMzE2MjkwMWwuMjc5MzE4LS42NDI5ODg3LjI5Nzc3MDctLjY1NjEwNTYuMzE2Nzg5NC0uNjY4MzA5Mi4zMzYzNzQtLjY3OTU5OTcuMzU2NTI0OS0uNjg5OTc3Yy4zNjY3ODg5LS42OTQ4NjExLjc2NDY1MjktMS40MDM5MTg0IDEuMTk2MTM5My0yLjEyMzA2MjQgNC43NDYzNTAxLTcuOTEwNTgzNCAxMi44Mzc3NDY5LTEzLjkwMDAyNTIgMTkuNDE0ODMyLTE0LjQ4NzY2ODYgNS4wNDUzODA2LS41MDU0MDk0IDkuODkyNTQzNi45Mjc2ODIzIDEzLjk0NDM2MjggMi44Nzk2NDM1bC42NDk5ODU4LjMyMDg1ODIuNjM1NDc2OC4zMjg2MDkzLjYyMDQwMTkuMzM1MDE1Yy4xMDIxMTI2LjA1NjI5NDkuMjAzNTczNi4xMTI4MDA3LjMwNDM3MS4xNjk0ODkybC41OTY3Mjg2LjM0MjEwMTMuNTgwMjM5LjM0NTE0MzkuNTYzMTgzNi4zNDY4NDExLjU0NTU2MjQuMzQ3MTkzMi41MjczNzUzLjM0NjE5OTkuNTA4NjIyMy4zNDM4NjE0Yy4wODMxNzYyLjA1NzA0MDYuMTY1NTQ3NS4xMTM5Mjc3LjI0NzEwMi4xNzA2MzMzbC40Nzk0MzIuMzM3ODMxMi40NTkyNjQ0LjMzMjEyOTQuNDM4NTMxLjMyNTA4MjUuNDE3MjMxNy4zMTY2OTAyLjU4NDY3MzYuNDU2MzU2OS41MzM1Njc0LjQyOTkwNzEuNjI4NjIzNy41MjQyMTc5LjY0NjM0MzIuNTYxNDAxNXptLTMwLjcwMDEwNTYgMTQuNTcxMzI0MyAyLjQ0MDk4MDEuODgxNDY1Yy4xMTMwMDgzLjg4NTIzMTkuMjczMTAzNCAxLjcyMzM3NzEuNDQxMDQ2NCAyLjQ4ODI3NjFsLjEwMTM5MzYuNDQ5OTQwNi0yLjcxMjIwMDEtLjk3MTg3MTctLjAzMzgzNDctLjIxMjE2MTgtLjA2NjA0MjEtLjQ3NTU4NDMtLjA2MTE2MDEtLjU0MTIxOTVjLS4wNDgwMjg1LS40Nzc0NjAyLS4wODc1ODE0LTEuMDE5OTAwMy0uMTEwMTgzMS0xLjYxODg0NDR6bTMxLjUwNjcyMzktNy42NjE5NjUyaC0xLjUxNDMxMTdjLS45NDAwMjM4IDAtMS4yMzkxMjI0LjQwOTc3Mi0xLjMzNDI5MDEuNjcwNTM2bC0uMDI4MjI2Ni4wOTUwMzM5Yy0uMDAzMjM3LjAxNDA3My0uMDA1ODI2Ni4wMjcxNTI2LS4wMDc4OTgyLjAzOTA3MzJsLS4wMDgxNTczLjA3MTUyMzktLjAwMDEyOTUgMy45MTUzODY0aDQuMTM2MTA1MWwtLjAwMTg1MzMtMy45MzQ3Njk0LS4wMTAyNjEyLS4wNjY5OTEzLS4wMjU3MjA3LS4wOTg3MjQxYy0uMDgzNTM1Ny0uMjU5MTUwNy0uMzUwOTEzNS0uNjkxMDY4Ni0xLjIwNTI1NjUtLjY5MTA2ODZ6bS01MC40OTIxMjQyLjMzOTAyNSAyLjU5OTE5MTcuOTQ5MjctLjQwODY0MS45NTE1ODM5Yy0uMjEyNDg4Mi40OTk0NjQ0LS40Mjc3Nzk2IDEuMDE0ODE0Mi0uNjAzMzU3NSAxLjQ1Nzc0NWwtLjExODA4NDkuMzAyODcxMi0yLjU5OTE5MTctLjk0OTI3LjEzMjM2NjItLjM0NTMwMzMuMjU4Mzg4OS0uNjM5MjAzNC4zMDU3MTExLS43MjgxOTc0LjMyNTQ4NzUtLjc1MzYyNDRjLjAzNjI0MzgtLjA4Mjc5NDMuMDcyMzQzNy0uMTY0ODgyMy4xMDgxMjk3LS4yNDU4NzE2em0zNS40NDUxMjA5LS4xNDM0NDQ5aC0zLjQ1Njg0Mzl2My42NTg4NjczaDMuNDM0Mzk2OGwuMDU0NzEwNi0uMDI1MzkyLjA4NjU5ODQtLjA0ODg5ODMuMTE0NzUzNi0uMDc4NjgyMmMuMjkyNjQyOC0uMjIxMTQ0OC43MzE2MDcxLS43MTQ5Nzk3LjczMTYwNzEtMS42ODc2ODQ3cy0uNDI4OTg3OC0xLjQ1NjU2MzQtLjcxNDk3OTctMS42NzEwNTczbC0uMTEyMTQ1NS0uMDc2MDc0MS0uMDg0NjMwMy0uMDQ2OTMwMXptLTE1LjQ0MjY0NTYtLjc2MDYyMTggMS42MjczMjAxIDEuMjg4Mjk1MWMtLjE4MDgxMzQuNzA1MTcyLS4zMTgyMzE1IDEuNDEwMzQ0LS40MTIyNTQ1IDIuMTE1NTE2bC0uMDYyMzgwNi41Mjg4NzktMS44MzA3MzUtMS40NDY1MDY3Yy4xODA4MTM0LS44MTM2Ni4zODQyMjg0LTEuNjQ5OTIxNy42NzgwNS0yLjQ4NjE4MzR6bTQuMDAwNDk1MS02LjMwNTg2NTEgMS4wMTcwNzUgMS41MzY5MTM0Yy0uMzk3Nzg5My40MTU4NzA3LS43NjY2NDg1LjgzMTc0MTMtMS4wOTUwMDU1IDEuMjcwNzU2MWwtLjIzODQ5MjguMzMzOTYyMy0xLjA4NDg4MDEtMS42MjczMjAxYy40MDY4My0uNTE5ODM4My44ODE0NjUxLTEuMDM5Njc2NyAxLjQwMTMwMzQtMS41MTQzMTE3em0tMTYuMTgyNzkzNi0zLjM0NTA0NjcgMS42MDQ3MTgzIDEuNDAxMzAzNGMtLjQwNjgzLjQyMzc4MTItLjgwMDk0NjUuODcyOTg5NC0xLjE3MjgxNDYgMS4zMjg1NTQybC0uMzY0MDk4Ny40NTY5Nzc1LTEuNzQwMzI4NC0xLjQ5MTcxMDFjLjUxOTgzODMtLjU2NTA0MTYgMS4wODQ4OC0xLjEzMDA4MzMgMS42NzI1MjM0LTEuNjk1MTI1em0yMi4zOTgyNTIxLS4wOTA0MDY3LjQ5NzIzNjYgMS40OTE3MTAxYy0uNTI0MzU4Ni4xNjI3MzItMS4wNDg3MTczLjM2ODg1OTItMS41NzMwNzYuNjA2ODA5NWwtLjM5MzI2OS4xODQyNDg4LS41MTk4Mzg0LTEuNTU5NTE1Yy41NjUwNDE3LS4yNDg2MTg0IDEuMjIwNDkwMS0uNDk3MjM2NyAxLjk4ODk0NjgtLjcyMzI1MzR6bTUuMjg4NzktLjU0MjQ0Yy41Nzg2MDI3LjAzNjE2MjcgMS4xNzE2NzA1LjEwMTI1NTUgMS43NzkyMDMzLjIwNjg1MDVsLjQ1ODM2MTguMDg2OTcxMi0uMDkwNDA2NyAxLjQwMTMwMzRjLS41OTY2ODQtLjEyNjU2OTQtMS4xOTMzNjgtLjIwOTc0MzUtMS43OTAwNTItLjI0OTUyMjRsLS40NDc1MTMtLjAyMTY5NzZ6bS0xOC41NTU5Njg2LTYuMjM4MDYwMSAxLjAxNzA3NSAxLjU1OTUxNWMtLjQ0MDczMjUuMjIwMzY2My0uODY4NzUxNi40NjYxNTk0LTEuMzAzMTI3NC43Mjc4NDQzbC0uNDM3MjAxLjI2NjYyOTEtMS4wMzk2NzY3LTEuNTgyMTE2N2MuNjEwMjQ1LS4zNjE2MjY3IDEuMTk3ODg4NC0uNjc4MDUgMS43NjI5MzAxLS45NzE4NzE3em0xOC41MTA3NjUzLjYzMjg0NjcuMDkwNDA2Ny0xLjQ5MTcxLjQ0MzUwNzMuMTMwNTU2NC4zODM5ODAzLjEyMDMyNTIuMzI4NTQ1OC4xMDk5MDc5LjI3NzIwMzcuMDk5MzA0OC4zMjg0OTE1LjEyODY2OS4yOTY0ODguMTMyNzExMi4xMzQxNDUxLjA2OTU4MzgtLjA5MDQwNjcgMS41MTQzMTE3Yy0uNDgyMTY4OS0uMTk1ODgxMS0uOTY0MzM3OC0uMzgxNzE3LTEuNDUzMjAzNS0uNTU3NTA3OHptLTguNTQzNDMwMS0yLjgyNTIwODQuNDUyMDMzMyAxLjM3ODcwMTdoLS4yMjYwMTY3Yy0uNDkxNTg2MiAwLS45ODMxNzI1LjAxMjcxMzQtMS40NzQ3NTg4LjA0NzY3NTRsLS40OTE1ODYyLjA0MjczMTMtLjQyOTQzMTctMS4zMzM0OTg0Yy43NDU4NTUtLjA5MDQwNjcgMS40NjkxMDg0LS4xMzU2MSAyLjE2OTc2MDEtLjEzNTYxeiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==">
|
48
|
+
</a>
|
49
|
+
</nav>
|
50
|
+
<ul class="bottom-0 left-0 list-none mx-8 mt-0 mb-8 right-0 absolute">
|
51
|
+
<li><strong>Rails version:</strong> <%= Rails.version %></li>
|
52
|
+
<li><strong>Ruby version:</strong> <%= RUBY_DESCRIPTION %></li>
|
53
|
+
</ul>
|
66
54
|
</div>
|
67
55
|
</body>
|
68
56
|
</html>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
pin
|
2
|
-
pin
|
3
|
-
pin
|
1
|
+
pin 'application'
|
2
|
+
pin '@hotwired/turbo-rails', to: 'turbo.min.js'
|
3
|
+
pin 'alpinejs'
|
@@ -1,8 +1,11 @@
|
|
1
1
|
class Auth::AuthenticatedSessionController < ApplicationController
|
2
|
-
|
2
|
+
include RedirectIfAuthenticated
|
3
|
+
|
4
|
+
skip_authenticate only: %i[new create]
|
5
|
+
skip_redirect_if_authenticated only: %i[destroy]
|
3
6
|
|
4
7
|
def new
|
5
|
-
render inertia:
|
8
|
+
render inertia: 'Auth/Login', props: {
|
6
9
|
canResetPassword: true,
|
7
10
|
status: flash[:status]
|
8
11
|
}
|
@@ -11,18 +14,18 @@ class Auth::AuthenticatedSessionController < ApplicationController
|
|
11
14
|
def create
|
12
15
|
form = Auth::LoginForm.new params.permit(:email, :password)
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
return redirect_back_or_to login_path, inertia: { errors: form.error_messages } if user.nil?
|
17
|
+
form.authenticate
|
17
18
|
|
18
|
-
|
19
|
+
return redirect_back_or_to login_path, inertia: { errors: form.error_messages } if Current.auth.user.nil?
|
19
20
|
|
20
21
|
redirect_to dashboard_path
|
21
22
|
end
|
22
23
|
|
23
24
|
def destroy
|
24
|
-
logout
|
25
|
+
Current.auth.logout
|
26
|
+
|
27
|
+
reset_session
|
25
28
|
|
26
|
-
redirect_to
|
29
|
+
redirect_to '/'
|
27
30
|
end
|
28
31
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
class Auth::NewPasswordController < ApplicationController
|
2
|
-
|
2
|
+
include RedirectIfAuthenticated
|
3
|
+
|
4
|
+
skip_authenticate
|
3
5
|
|
4
6
|
def new
|
5
|
-
render inertia:
|
7
|
+
render inertia: 'Auth/ResetPassword', props: {
|
6
8
|
token: params[:token]
|
7
9
|
}
|
8
10
|
end
|
@@ -10,7 +12,7 @@ class Auth::NewPasswordController < ApplicationController
|
|
10
12
|
def create
|
11
13
|
form = Auth::NewPasswordForm.new params.permit(:token, :password, :password_confirmation)
|
12
14
|
|
13
|
-
return redirect_to login_path, flash: { status:
|
15
|
+
return redirect_to login_path, flash: { status: 'Your password has been reset.' } if form.reset?
|
14
16
|
|
15
17
|
redirect_back_or_to password_reset_path(token: form.token),
|
16
18
|
inertia: { errors: form.error_messages }
|
@@ -1,8 +1,10 @@
|
|
1
1
|
class Auth::PasswordResetLinkController < ApplicationController
|
2
|
-
|
2
|
+
include RedirectIfAuthenticated
|
3
|
+
|
4
|
+
skip_authenticate
|
3
5
|
|
4
6
|
def new
|
5
|
-
render inertia:
|
7
|
+
render inertia: 'Auth/ForgotPassword', props: {
|
6
8
|
status: flash[:status]
|
7
9
|
}
|
8
10
|
end
|
@@ -12,6 +14,6 @@ class Auth::PasswordResetLinkController < ApplicationController
|
|
12
14
|
|
13
15
|
return redirect_back_or_to password_request_path, inertia: { errors: form.error_messages } unless form.send_reset_link?
|
14
16
|
|
15
|
-
redirect_back_or_to password_request_path, flash: { status:
|
17
|
+
redirect_back_or_to password_request_path, flash: { status: 'We have emailed your password reset link.' }
|
16
18
|
end
|
17
19
|
end
|