plutonium 0.34.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium/skill.md +53 -0
  3. data/.claude/skills/{assets → plutonium-assets}/SKILL.md +13 -8
  4. data/.claude/skills/{connect-resource → plutonium-connect-resource}/SKILL.md +1 -1
  5. data/.claude/skills/{controller → plutonium-controller}/SKILL.md +27 -13
  6. data/.claude/skills/{create-resource → plutonium-create-resource}/SKILL.md +1 -1
  7. data/.claude/skills/{definition → plutonium-definition}/SKILL.md +10 -10
  8. data/.claude/skills/{definition-actions → plutonium-definition-actions}/SKILL.md +34 -9
  9. data/.claude/skills/{definition-fields → plutonium-definition-fields}/SKILL.md +38 -10
  10. data/.claude/skills/plutonium-definition-query/SKILL.md +356 -0
  11. data/.claude/skills/{forms → plutonium-forms}/SKILL.md +6 -6
  12. data/.claude/skills/{installation → plutonium-installation}/SKILL.md +9 -9
  13. data/.claude/skills/{interaction → plutonium-interaction}/SKILL.md +20 -19
  14. data/.claude/skills/{model → plutonium-model}/SKILL.md +3 -3
  15. data/.claude/skills/{model-features → plutonium-model-features}/SKILL.md +3 -3
  16. data/.claude/skills/{nested-resources → plutonium-nested-resources}/SKILL.md +5 -5
  17. data/.claude/skills/{package → plutonium-package}/SKILL.md +7 -8
  18. data/.claude/skills/{policy → plutonium-policy}/SKILL.md +26 -4
  19. data/.claude/skills/{portal → plutonium-portal}/SKILL.md +33 -31
  20. data/.claude/skills/{resource → plutonium-resource}/SKILL.md +27 -27
  21. data/.claude/skills/{rodauth → plutonium-rodauth}/SKILL.md +5 -5
  22. data/.claude/skills/plutonium-theming/SKILL.md +424 -0
  23. data/.claude/skills/{views → plutonium-views}/SKILL.md +7 -7
  24. data/CHANGELOG.md +52 -0
  25. data/CLAUDE.md +215 -0
  26. data/CONTRIBUTING.md +72 -18
  27. data/README.md +100 -19
  28. data/app/assets/plutonium.css +1 -11
  29. data/app/assets/plutonium.js +1685 -1146
  30. data/app/assets/plutonium.js.map +4 -4
  31. data/app/assets/plutonium.min.js +70 -70
  32. data/app/assets/plutonium.min.js.map +4 -4
  33. data/app/views/resource/interactive_bulk_action.html.erb +1 -5
  34. data/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
  35. data/app/views/rodauth/_login_form.html.erb +15 -55
  36. data/app/views/rodauth/_login_form_footer.html.erb +2 -2
  37. data/app/views/rodauth/_password_visibility.html.erb +2 -8
  38. data/app/views/rodauth/add_recovery_codes.html.erb +2 -2
  39. data/app/views/rodauth/change_login.html.erb +36 -19
  40. data/app/views/rodauth/change_password.html.erb +34 -10
  41. data/app/views/rodauth/close_account.html.erb +12 -4
  42. data/app/views/rodauth/confirm_password.html.erb +19 -17
  43. data/app/views/rodauth/create_account.html.erb +30 -109
  44. data/app/views/rodauth/email_auth.html.erb +1 -1
  45. data/app/views/rodauth/logout.html.erb +4 -4
  46. data/app/views/rodauth/otp_auth.html.erb +13 -4
  47. data/app/views/rodauth/otp_disable.html.erb +12 -4
  48. data/app/views/rodauth/otp_setup.html.erb +29 -12
  49. data/app/views/rodauth/otp_unlock.html.erb +19 -10
  50. data/app/views/rodauth/otp_unlock_not_available.html.erb +7 -7
  51. data/app/views/rodauth/recovery_auth.html.erb +12 -4
  52. data/app/views/rodauth/recovery_codes.html.erb +12 -4
  53. data/app/views/rodauth/remember.html.erb +7 -7
  54. data/app/views/rodauth/reset_password.html.erb +23 -7
  55. data/app/views/rodauth/reset_password_request.html.erb +14 -10
  56. data/app/views/rodauth/sms_auth.html.erb +13 -4
  57. data/app/views/rodauth/sms_confirm.html.erb +13 -4
  58. data/app/views/rodauth/sms_disable.html.erb +12 -4
  59. data/app/views/rodauth/sms_request.html.erb +1 -1
  60. data/app/views/rodauth/sms_setup.html.erb +23 -7
  61. data/app/views/rodauth/two_factor_auth.html.erb +2 -2
  62. data/app/views/rodauth/two_factor_disable.html.erb +12 -4
  63. data/app/views/rodauth/two_factor_manage.html.erb +7 -7
  64. data/app/views/rodauth/unlock_account.html.erb +13 -5
  65. data/app/views/rodauth/unlock_account_request.html.erb +2 -2
  66. data/app/views/rodauth/verify_account.html.erb +25 -7
  67. data/app/views/rodauth/verify_account_resend.html.erb +14 -10
  68. data/app/views/rodauth/verify_login_change.html.erb +1 -1
  69. data/app/views/rodauth/webauthn_auth.html.erb +1 -1
  70. data/app/views/rodauth/webauthn_remove.html.erb +18 -8
  71. data/app/views/rodauth/webauthn_setup.html.erb +12 -4
  72. data/docs/.vitepress/config.ts +15 -26
  73. data/docs/.vitepress/theme/custom.css +388 -29
  74. data/docs/getting-started/index.md +1 -1
  75. data/docs/getting-started/tutorial/02-first-resource.md +9 -0
  76. data/docs/getting-started/tutorial/06-nested-resources.md +2 -2
  77. data/docs/getting-started/tutorial/07-author-portal.md +191 -0
  78. data/docs/getting-started/tutorial/{07-customizing-ui.md → 08-customizing-ui.md} +7 -7
  79. data/docs/getting-started/tutorial/index.md +5 -2
  80. data/docs/guides/authorization.md +33 -0
  81. data/docs/guides/creating-packages.md +12 -16
  82. data/docs/guides/custom-actions.md +36 -0
  83. data/docs/guides/search-filtering.md +121 -42
  84. data/docs/guides/theming.md +232 -36
  85. data/docs/index.md +203 -57
  86. data/docs/public/og-image.png +0 -0
  87. data/docs/reference/controller/index.md +14 -16
  88. data/docs/reference/definition/actions.md +38 -3
  89. data/docs/reference/definition/fields.md +3 -3
  90. data/docs/reference/definition/index.md +2 -2
  91. data/docs/reference/generators/index.md +0 -1
  92. data/docs/reference/interaction/index.md +14 -10
  93. data/docs/reference/model/index.md +0 -1
  94. data/docs/reference/portal/index.md +13 -27
  95. data/gemfiles/rails_7.gemfile.lock +1 -1
  96. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  97. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  98. data/lib/generators/pu/pkg/portal/portal_generator.rb +0 -2
  99. data/lib/generators/pu/pkg/portal/templates/app/views/package/dashboard/index.html.erb +28 -72
  100. data/lib/plutonium/action/interactive.rb +2 -2
  101. data/lib/plutonium/core/controller.rb +2 -1
  102. data/lib/plutonium/definition/actions.rb +2 -2
  103. data/lib/plutonium/lib/deep_freezer.rb +3 -7
  104. data/lib/plutonium/query/filter.rb +14 -0
  105. data/lib/plutonium/query/filters/association.rb +49 -0
  106. data/lib/plutonium/query/filters/boolean.rb +35 -0
  107. data/lib/plutonium/query/filters/date.rb +97 -0
  108. data/lib/plutonium/query/filters/date_range.rb +58 -0
  109. data/lib/plutonium/query/filters/select.rb +55 -0
  110. data/lib/plutonium/resource/controllers/crud_actions.rb +24 -6
  111. data/lib/plutonium/resource/controllers/interactive_actions.rb +76 -58
  112. data/lib/plutonium/resource/controllers/queryable.rb +4 -2
  113. data/lib/plutonium/resource/query_object.rb +1 -1
  114. data/lib/plutonium/ui/action_button.rb +23 -65
  115. data/lib/plutonium/ui/actions_dropdown.rb +103 -0
  116. data/lib/plutonium/ui/block.rb +1 -1
  117. data/lib/plutonium/ui/breadcrumbs.rb +12 -19
  118. data/lib/plutonium/ui/color_mode_selector.rb +1 -1
  119. data/lib/plutonium/ui/component/kit.rb +6 -0
  120. data/lib/plutonium/ui/component_classes.rb +102 -0
  121. data/lib/plutonium/ui/display/base.rb +15 -0
  122. data/lib/plutonium/ui/display/components/attachment.rb +6 -5
  123. data/lib/plutonium/ui/display/components/boolean.rb +23 -0
  124. data/lib/plutonium/ui/display/components/color.rb +23 -0
  125. data/lib/plutonium/ui/display/resource.rb +1 -1
  126. data/lib/plutonium/ui/display/theme.rb +29 -15
  127. data/lib/plutonium/ui/empty_card.rb +3 -3
  128. data/lib/plutonium/ui/form/base.rb +20 -0
  129. data/lib/plutonium/ui/form/components/key_value_store.rb +11 -11
  130. data/lib/plutonium/ui/form/components/resource_select.rb +31 -0
  131. data/lib/plutonium/ui/form/components/secure_association.rb +1 -2
  132. data/lib/plutonium/ui/form/components/uppy.rb +5 -4
  133. data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +4 -4
  134. data/lib/plutonium/ui/form/interaction.rb +17 -1
  135. data/lib/plutonium/ui/form/query.rb +133 -80
  136. data/lib/plutonium/ui/form/theme.rb +50 -35
  137. data/lib/plutonium/ui/frame_navigator_panel.rb +2 -2
  138. data/lib/plutonium/ui/layout/base.rb +1 -1
  139. data/lib/plutonium/ui/layout/header.rb +4 -7
  140. data/lib/plutonium/ui/layout/rodauth_layout.rb +7 -7
  141. data/lib/plutonium/ui/layout/sidebar.rb +1 -1
  142. data/lib/plutonium/ui/nav_grid_menu.rb +7 -6
  143. data/lib/plutonium/ui/nav_user.rb +9 -8
  144. data/lib/plutonium/ui/page/interactive_action.rb +5 -5
  145. data/lib/plutonium/ui/page_header.rb +29 -10
  146. data/lib/plutonium/ui/panel.rb +4 -4
  147. data/lib/plutonium/ui/sidebar_menu.rb +8 -8
  148. data/lib/plutonium/ui/skeleton_table.rb +7 -8
  149. data/lib/plutonium/ui/tab_list.rb +5 -5
  150. data/lib/plutonium/ui/table/base.rb +3 -0
  151. data/lib/plutonium/ui/table/components/attachment.rb +4 -3
  152. data/lib/plutonium/ui/table/components/bulk_actions_toolbar.rb +82 -0
  153. data/lib/plutonium/ui/table/components/pagy_info.rb +2 -2
  154. data/lib/plutonium/ui/table/components/pagy_pagination.rb +13 -8
  155. data/lib/plutonium/ui/table/components/row_actions_dropdown.rb +101 -0
  156. data/lib/plutonium/ui/table/components/scopes_bar.rb +2 -2
  157. data/lib/plutonium/ui/table/components/selection_column.rb +100 -0
  158. data/lib/plutonium/ui/table/display_theme.rb +6 -6
  159. data/lib/plutonium/ui/table/resource.rb +93 -52
  160. data/lib/plutonium/ui/table/theme.rb +28 -15
  161. data/lib/plutonium/version.rb +1 -1
  162. data/package.json +2 -2
  163. data/plutonium.gemspec +5 -4
  164. data/src/css/components.css +471 -0
  165. data/src/css/intl_tel_input.css +2 -2
  166. data/src/css/plutonium.css +2 -0
  167. data/src/css/tokens.css +149 -0
  168. data/src/js/controllers/bulk_actions_controller.js +109 -0
  169. data/src/js/controllers/filter_panel_controller.js +35 -0
  170. data/src/js/controllers/register_controllers.js +5 -1
  171. data/src/js/controllers/resource_drop_down_controller.js +25 -1
  172. data/src/js/controllers/slim_select_controller.js +6 -2
  173. data/src/js/turbo/turbo_actions.js +1 -1
  174. metadata +52 -39
  175. data/.claude/skills/definition-query/SKILL.md +0 -334
  176. data/docs/concepts/architecture.md +0 -226
  177. data/docs/concepts/auto-detection.md +0 -254
  178. data/docs/concepts/index.md +0 -61
  179. data/docs/concepts/packages-portals.md +0 -304
  180. data/docs/concepts/resources.md +0 -224
  181. data/docs/cookbook/blog.md +0 -411
  182. data/docs/cookbook/index.md +0 -289
  183. data/docs/cookbook/saas.md +0 -481
  184. data/docs/public/CLAUDE.md +0 -578
  185. data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +0 -5
@@ -1,7 +1,7 @@
1
- <div class="mb-4 text-sm text-gray-500 dark:text-gray-400">
1
+ <div class="mb-4 text-sm text-[var(--pu-text-muted)]">
2
2
  <%== rodauth.unlock_account_request_explanatory_text %>
3
3
  </div>
4
4
  <%= form_with url: rodauth.unlock_account_request_path, method: :post, data: { turbo: false }, class: "space-y-4" do |form| %>
5
5
  <%= form.hidden_field rodauth.login_param, value: params[rodauth.login_param] %>
6
- <%= form.submit rodauth.unlock_account_request_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
6
+ <%= form.submit rodauth.unlock_account_request_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
7
7
  <% end %>
@@ -1,20 +1,38 @@
1
1
  <%= form_with url: rodauth.verify_account_path, method: :post, data: { turbo: false, controller: "password-visibility" }, class: "space-y-4" do |form| %>
2
2
  <% if rodauth.verify_account_set_password? %>
3
3
  <div>
4
- <%= form.label "password", rodauth.password_label, class: "block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
5
- <%= form.password_field rodauth.password_param, value: "", data: {password_visibility_target: "password"}, id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
6
- <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
4
+ <%= form.label "password", rodauth.password_label, class: "pu-label" %>
5
+ <%= form.password_field rodauth.password_param,
6
+ value: "",
7
+ data: { password_visibility_target: "password" },
8
+ id: "password",
9
+ autocomplete: rodauth.password_field_autocomplete_value,
10
+ required: true,
11
+ class: "pu-input #{rodauth.field_error(rodauth.password_param) ? 'pu-input-invalid' : ''}",
12
+ aria: (rodauth.field_error(rodauth.password_param) ? { invalid: true, describedby: "password_error_message" } : nil) %>
13
+ <% if rodauth.field_error(rodauth.password_param) %>
14
+ <span class="pu-error" id="password_error_message"><%= rodauth.field_error(rodauth.password_param) %></span>
15
+ <% end %>
7
16
  </div>
8
17
 
9
18
  <% if rodauth.require_password_confirmation? %>
10
19
  <div>
11
- <%= form.label "password-confirm", rodauth.password_confirm_label, class: "block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
12
- <%= form.password_field rodauth.password_confirm_param, value: "", data: {password_visibility_target: "password"}, id: "password-confirm", autocomplete: "new-password", required: true, class: "bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_confirm_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "password-confirm_error_message" } if rodauth.field_error(rodauth.password_confirm_param)) %>
13
- <%= content_tag(:span, rodauth.field_error(rodauth.password_confirm_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "password-confirm_error_message") if rodauth.field_error(rodauth.password_confirm_param) %>
20
+ <%= form.label "password-confirm", rodauth.password_confirm_label, class: "pu-label" %>
21
+ <%= form.password_field rodauth.password_confirm_param,
22
+ value: "",
23
+ data: { password_visibility_target: "password" },
24
+ id: "password-confirm",
25
+ autocomplete: "new-password",
26
+ required: true,
27
+ class: "pu-input #{rodauth.field_error(rodauth.password_confirm_param) ? 'pu-input-invalid' : ''}",
28
+ aria: (rodauth.field_error(rodauth.password_confirm_param) ? { invalid: true, describedby: "password-confirm_error_message" } : nil) %>
29
+ <% if rodauth.field_error(rodauth.password_confirm_param) %>
30
+ <span class="pu-error" id="password-confirm_error_message"><%= rodauth.field_error(rodauth.password_confirm_param) %></span>
31
+ <% end %>
14
32
  </div>
15
33
  <% end %>
16
34
  <%= render "password_visibility" %>
17
35
  <% end %>
18
36
 
19
- <%= form.submit rodauth.verify_account_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
37
+ <%= form.submit rodauth.verify_account_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
20
38
  <% end %>
@@ -1,4 +1,4 @@
1
- <div class="mb-4 text-sm text-gray-500 dark:text-gray-400">
1
+ <div class="mb-4 text-sm text-[var(--pu-text-muted)]">
2
2
  <%== rodauth.verify_account_resend_explanatory_text %>
3
3
  </div>
4
4
  <%= form_with url: rodauth.verify_account_resend_path, method: :post, data: { turbo: false }, class: "space-y-4" do |form| %>
@@ -6,15 +6,19 @@
6
6
  <%= form.hidden_field rodauth.login_param, value: params[rodauth.login_param] %>
7
7
  <% else %>
8
8
  <div>
9
- <%= form.label "login", rodauth.login_label, class: "block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
10
- <%= form.email_field rodauth.login_param, value: params[rodauth.login_param],
11
- id: "login",
12
- autocomplete: "email",
13
- required: true,
14
- placeholder: "jane@acme.inc",
15
- class: "bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.login_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "login_error_message" } if rodauth.field_error(rodauth.login_param)) %>
16
- <%= content_tag(:span, rodauth.field_error(rodauth.login_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "login_error_message") if rodauth.field_error(rodauth.login_param) %>
9
+ <%= form.label "login", rodauth.login_label, class: "pu-label" %>
10
+ <%= form.email_field rodauth.login_param,
11
+ value: params[rodauth.login_param],
12
+ id: "login",
13
+ autocomplete: "email",
14
+ required: true,
15
+ placeholder: "jane@acme.inc",
16
+ class: "pu-input #{rodauth.field_error(rodauth.login_param) ? 'pu-input-invalid' : ''}",
17
+ aria: (rodauth.field_error(rodauth.login_param) ? { invalid: true, describedby: "login_error_message" } : nil) %>
18
+ <% if rodauth.field_error(rodauth.login_param) %>
19
+ <span class="pu-error" id="login_error_message"><%= rodauth.field_error(rodauth.login_param) %></span>
20
+ <% end %>
17
21
  </div>
18
22
  <% end %>
19
- <%= form.submit rodauth.verify_account_resend_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
23
+ <%= form.submit rodauth.verify_account_resend_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
20
24
  <% end %>
@@ -1,3 +1,3 @@
1
1
  <%= form_with url: rodauth.verify_login_change_path, method: :post, data: { turbo: false }, class: "space-y-4" do |form| %>
2
- <%= form.submit rodauth.verify_login_change_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
2
+ <%= form.submit rodauth.verify_login_change_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
3
3
  <% end %>
@@ -6,7 +6,7 @@
6
6
  <%= form.hidden_field rodauth.webauthn_auth_challenge_hmac_param, value: rodauth.compute_hmac(cred.challenge) %>
7
7
  <%= form.text_field rodauth.webauthn_auth_param, value: "", id: "webauthn-auth", class: "hidden", aria: { hidden: "true" } %>
8
8
  <div id="webauthn-auth-button">
9
- <%= form.submit rodauth.webauthn_auth_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
9
+ <%= form.submit rodauth.webauthn_auth_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
10
10
  </div>
11
11
  <% end %>
12
12
 
@@ -1,22 +1,32 @@
1
1
  <%= form_with url: rodauth.webauthn_remove_path, method: :post, id: "webauthn-remove-form", data: { turbo: false }, class: "space-y-4" do |form| %>
2
2
  <% if rodauth.two_factor_modifications_require_password? %>
3
3
  <div>
4
- <%= form.label "password", rodauth.password_label, class: "block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
5
- <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
6
- <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
4
+ <%= form.label "password", rodauth.password_label, class: "pu-label" %>
5
+ <%= form.password_field rodauth.password_param,
6
+ value: "",
7
+ id: "password",
8
+ autocomplete: rodauth.password_field_autocomplete_value,
9
+ required: true,
10
+ class: "pu-input #{rodauth.field_error(rodauth.password_param) ? 'pu-input-invalid' : ''}",
11
+ aria: (rodauth.field_error(rodauth.password_param) ? { invalid: true, describedby: "password_error_message" } : nil) %>
12
+ <% if rodauth.field_error(rodauth.password_param) %>
13
+ <span class="pu-error" id="password_error_message"><%= rodauth.field_error(rodauth.password_param) %></span>
14
+ <% end %>
7
15
  </div>
8
16
  <% end %>
9
17
 
10
- <fieldset class="mb-6">
18
+ <fieldset class="mb-6 space-y-2">
11
19
  <% rodauth.account_webauthn_usage.each do |id, last_use| %>
12
20
  <div class="flex items-center space-x-2">
13
21
  <% last_use = last_use.strftime(rodauth.strftime_format) if last_use.is_a?(Time) %>
14
- <%= form.radio_button rodauth.webauthn_remove_param, id, id: "webauthn-remove-#{id}", class: "dark:bg-gray-900 dark:border-gray-600 dark:checked:bg-current dark:checked:border-current dark:checked:text-emerald-400 dark:focus:ring-emerald-400 dark:focus:ring-offset-gray-900" %>
15
- <%= form.label "webauthn-remove-#{id}", "Last use: #{last_use}", class: "text-sm" %>
22
+ <%= form.radio_button rodauth.webauthn_remove_param, id, id: "webauthn-remove-#{id}", class: "pu-checkbox" %>
23
+ <%= form.label "webauthn-remove-#{id}", "Last use: #{last_use}", class: "text-sm text-[var(--pu-text)]" %>
16
24
  </div>
17
25
  <% end %>
18
- <%= content_tag(:span, rodauth.field_error(rodauth.webauthn_remove_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "webauthn_remove_error_message") if rodauth.field_error(rodauth.webauthn_remove_param) %>
26
+ <% if rodauth.field_error(rodauth.webauthn_remove_param) %>
27
+ <span class="pu-error" id="webauthn_remove_error_message"><%= rodauth.field_error(rodauth.webauthn_remove_param) %></span>
28
+ <% end %>
19
29
  </fieldset>
20
30
 
21
- <%= form.submit rodauth.webauthn_remove_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
31
+ <%= form.submit rodauth.webauthn_remove_button, class: "w-full pu-btn pu-btn-md pu-btn-warning" %>
22
32
  <% end %>
@@ -7,14 +7,22 @@
7
7
 
8
8
  <% if rodauth.two_factor_modifications_require_password? %>
9
9
  <div>
10
- <%= form.label "password", rodauth.password_label, class: "block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
11
- <%= form.password_field rodauth.password_param, value: "", id: "password", autocomplete: rodauth.password_field_autocomplete_value, required: true, class: "bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "password_error_message" } if rodauth.field_error(rodauth.password_param)) %>
12
- <%= content_tag(:span, rodauth.field_error(rodauth.password_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "password_error_message") if rodauth.field_error(rodauth.password_param) %>
10
+ <%= form.label "password", rodauth.password_label, class: "pu-label" %>
11
+ <%= form.password_field rodauth.password_param,
12
+ value: "",
13
+ id: "password",
14
+ autocomplete: rodauth.password_field_autocomplete_value,
15
+ required: true,
16
+ class: "pu-input #{rodauth.field_error(rodauth.password_param) ? 'pu-input-invalid' : ''}",
17
+ aria: (rodauth.field_error(rodauth.password_param) ? { invalid: true, describedby: "password_error_message" } : nil) %>
18
+ <% if rodauth.field_error(rodauth.password_param) %>
19
+ <span class="pu-error" id="password_error_message"><%= rodauth.field_error(rodauth.password_param) %></span>
20
+ <% end %>
13
21
  </div>
14
22
  <% end %>
15
23
 
16
24
  <div id="webauthn-setup-button">
17
- <%= form.submit rodauth.webauthn_setup_button, class: "w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
25
+ <%= form.submit rodauth.webauthn_setup_button, class: "w-full pu-btn pu-btn-md pu-btn-primary" %>
18
26
  </div>
19
27
  <% end %>
20
28
 
@@ -7,8 +7,19 @@ const base = "/plutonium-core/"
7
7
  export default defineConfig(withMermaid({
8
8
  base: base,
9
9
  title: "Plutonium",
10
- description: "Rapid Application Development for Rails",
11
- head: [["link", { rel: "icon", href: `${base}favicon.ico` }]],
10
+ description: "Build production-ready Rails apps in minutes, not days",
11
+ head: [
12
+ ["link", { rel: "icon", href: `${base}favicon.ico` }],
13
+ ["meta", { property: "og:type", content: "website" }],
14
+ ["meta", { property: "og:title", content: "Plutonium - Build Production-Ready Rails Apps in Minutes" }],
15
+ ["meta", { property: "og:description", content: "Build production-ready Rails applications in minutes, not days. Convention-driven, fully customizable. Built for the AI era." }],
16
+ ["meta", { property: "og:image", content: "https://radioactive-labs.github.io/plutonium-core/og-image.png" }],
17
+ ["meta", { property: "og:url", content: "https://radioactive-labs.github.io/plutonium-core/" }],
18
+ ["meta", { name: "twitter:card", content: "summary_large_image" }],
19
+ ["meta", { name: "twitter:title", content: "Plutonium - Build Production-Ready Rails Apps in Minutes" }],
20
+ ["meta", { name: "twitter:description", content: "Build production-ready Rails applications in minutes, not days. Convention-driven, fully customizable. Built for the AI era." }],
21
+ ["meta", { name: "twitter:image", content: "https://radioactive-labs.github.io/plutonium-core/og-image.png" }],
22
+ ],
12
23
  ignoreDeadLinks: 'localhostLinks',
13
24
  themeConfig: {
14
25
  // https://vitepress.dev/reference/default-theme-config
@@ -21,7 +32,6 @@ export default defineConfig(withMermaid({
21
32
  { text: "Getting Started", link: "/getting-started/" },
22
33
  { text: "Guides", link: "/guides/" },
23
34
  { text: "Reference", link: "/reference/" },
24
- { text: "Cookbook", link: "/cookbook/" },
25
35
  { text: "Demo", link: "https://github.com/radioactive-labs/plutonium-core/tree/master/test/dummy" }
26
36
  ],
27
37
  sidebar: {
@@ -44,19 +54,8 @@ export default defineConfig(withMermaid({
44
54
  { text: "4. Authorization", link: "/getting-started/tutorial/04-authorization" },
45
55
  { text: "5. Custom Actions", link: "/getting-started/tutorial/05-custom-actions" },
46
56
  { text: "6. Nested Resources", link: "/getting-started/tutorial/06-nested-resources" },
47
- { text: "7. Customizing UI", link: "/getting-started/tutorial/07-customizing-ui" },
48
- ]
49
- }
50
- ],
51
- '/concepts/': [
52
- {
53
- text: "Core Concepts",
54
- items: [
55
- { text: "Overview", link: "/concepts/" },
56
- { text: "Architecture", link: "/concepts/architecture" },
57
- { text: "Resources", link: "/concepts/resources" },
58
- { text: "Packages & Portals", link: "/concepts/packages-portals" },
59
- { text: "Auto-Detection", link: "/concepts/auto-detection" },
57
+ { text: "7. Author Portal", link: "/getting-started/tutorial/07-author-portal" },
58
+ { text: "8. Customizing UI", link: "/getting-started/tutorial/08-customizing-ui" },
60
59
  ]
61
60
  }
62
61
  ],
@@ -167,16 +166,6 @@ export default defineConfig(withMermaid({
167
166
  ]
168
167
  }
169
168
  ],
170
- '/cookbook/': [
171
- {
172
- text: "Cookbook",
173
- items: [
174
- { text: "Overview", link: "/cookbook/" },
175
- { text: "Blog Application", link: "/cookbook/blog" },
176
- { text: "SaaS Application", link: "/cookbook/saas" },
177
- ]
178
- }
179
- ]
180
169
  },
181
170
  socialLinks: [
182
171
  { icon: "github", link: "https://github.com/radioactive-labs/plutonium-core" }