kaze 1.3.1 → 2.0.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 (263) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -1
  3. data/README.md +1 -1
  4. data/lib/kaze/commands/app/hotwire_stack.rb +2 -0
  5. data/lib/kaze/commands/app/inertia_react_stack.rb +5 -1
  6. data/lib/kaze/commands/app/inertia_vue_stack.rb +5 -1
  7. data/lib/kaze/commands/app.rb +9 -2
  8. data/lib/kaze/version.rb +1 -1
  9. data/stubs/default/config/routes.rb +11 -4
  10. data/stubs/default/test/integration/appearance_test.rb +11 -0
  11. data/stubs/default/test/integration/password_update_test.rb +9 -1
  12. data/stubs/hotwire/app/assets/tailwind/application.css +123 -0
  13. data/stubs/hotwire/app/components/breadcrumbs_component.rb +32 -0
  14. data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
  15. data/stubs/hotwire/app/components/dropdown_component.html.erb +2 -2
  16. data/stubs/hotwire/app/components/dropdown_component.rb +5 -1
  17. data/stubs/hotwire/app/components/dropdown_link_component.rb +1 -1
  18. data/stubs/hotwire/app/components/heading_component.rb +19 -0
  19. data/stubs/hotwire/app/components/icon_component.rb +30 -0
  20. data/stubs/hotwire/app/components/input_error_component.rb +1 -1
  21. data/stubs/hotwire/app/components/input_label_component.rb +3 -3
  22. data/stubs/hotwire/app/components/modal_component.html.erb +2 -2
  23. data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
  24. data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
  25. data/stubs/hotwire/app/components/sidebar_menu_button_component.rb +25 -0
  26. data/stubs/hotwire/app/components/text_input_component.rb +1 -1
  27. data/stubs/hotwire/app/components/user_avatar_component.rb +27 -0
  28. data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
  29. data/stubs/hotwire/app/controllers/concerns/sidebar_state.rb +14 -0
  30. data/stubs/hotwire/app/controllers/settings/appearance_controller.rb +7 -0
  31. data/stubs/hotwire/app/controllers/settings/password_controller.rb +19 -0
  32. data/stubs/hotwire/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +3 -4
  33. data/stubs/hotwire/app/views/auth/login.html.erb +1 -1
  34. data/stubs/hotwire/app/views/dashboard/index.html.erb +6 -11
  35. data/stubs/hotwire/app/views/layouts/_appearance.html.erb +18 -0
  36. data/stubs/hotwire/app/views/layouts/_settings.html.erb +26 -0
  37. data/stubs/hotwire/app/views/layouts/_sidebar.html.erb +56 -0
  38. data/stubs/hotwire/app/views/layouts/_sidebar_header.html.erb +11 -0
  39. data/stubs/hotwire/app/views/layouts/_sidebar_user.html.erb +34 -0
  40. data/stubs/hotwire/app/views/layouts/application.html.erb +25 -15
  41. data/stubs/hotwire/app/views/layouts/guest.html.erb +1 -0
  42. data/stubs/hotwire/app/views/settings/appearance/_update_appearance_form.html.erb +28 -0
  43. data/stubs/hotwire/app/views/settings/appearance/edit.html.erb +10 -0
  44. data/stubs/hotwire/app/views/{profile/partials → settings/password}/_update_password_form.html.erb +2 -10
  45. data/stubs/hotwire/app/views/settings/password/edit.html.erb +10 -0
  46. data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_confirm_user_deletion_modal.html.erb +2 -2
  47. data/stubs/hotwire/app/views/settings/profile/_delete_user_form.html.erb +6 -0
  48. data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_update_profile_information_form.html.erb +4 -12
  49. data/stubs/hotwire/app/views/{profile → settings/profile}/destroy.turbo_stream.erb +1 -1
  50. data/stubs/hotwire/app/views/settings/profile/edit.html.erb +14 -0
  51. data/stubs/hotwire/app/views/welcome/index.html.erb +1 -0
  52. data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +4 -1
  53. data/stubs/inertia-common/app/controllers/settings/appearance_controller.rb +7 -0
  54. data/stubs/inertia-common/app/controllers/settings/password_controller.rb +17 -0
  55. data/stubs/inertia-common/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +2 -2
  56. data/stubs/inertia-common/test/integration/appearance_test.rb +11 -0
  57. data/stubs/inertia-common/test/integration/password_update_test.rb +10 -2
  58. data/stubs/inertia-react-ts/app/assets/tailwind/application.css +124 -0
  59. data/stubs/inertia-react-ts/app/javascript/Components/AppLogo.tsx +17 -0
  60. data/stubs/inertia-react-ts/app/javascript/Components/AppShell.tsx +9 -0
  61. data/stubs/inertia-react-ts/app/javascript/Components/AppSidebar.tsx +65 -0
  62. data/stubs/inertia-react-ts/app/javascript/Components/AppSidebarHeader.tsx +14 -0
  63. data/stubs/inertia-react-ts/app/javascript/Components/Breadcrumbs.tsx +43 -0
  64. data/stubs/inertia-react-ts/app/javascript/Components/Heading.tsx +19 -0
  65. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +1 -1
  66. data/stubs/inertia-react-ts/app/javascript/Components/NavFooter.tsx +32 -0
  67. data/stubs/inertia-react-ts/app/javascript/Components/NavMain.tsx +32 -0
  68. data/stubs/inertia-react-ts/app/javascript/Components/NavUser.tsx +39 -0
  69. data/stubs/inertia-react-ts/app/javascript/Components/UserInfo.tsx +23 -0
  70. data/stubs/inertia-react-ts/app/javascript/Components/UserMenuContent.tsx +57 -0
  71. data/stubs/inertia-react-ts/app/javascript/Components/ui/avatar.tsx +51 -0
  72. data/stubs/inertia-react-ts/app/javascript/Components/ui/breadcrumb.tsx +109 -0
  73. data/stubs/inertia-react-ts/app/javascript/Components/ui/button.tsx +49 -0
  74. data/stubs/inertia-react-ts/app/javascript/Components/ui/checkbox.tsx +27 -0
  75. data/stubs/inertia-react-ts/app/javascript/Components/ui/dialog.tsx +109 -0
  76. data/stubs/inertia-react-ts/app/javascript/Components/ui/dropdown-menu.tsx +217 -0
  77. data/stubs/inertia-react-ts/app/javascript/Components/ui/input.tsx +21 -0
  78. data/stubs/inertia-react-ts/app/javascript/Components/ui/label.tsx +19 -0
  79. data/stubs/inertia-react-ts/app/javascript/Components/ui/separator.tsx +26 -0
  80. data/stubs/inertia-react-ts/app/javascript/Components/ui/sheet.tsx +137 -0
  81. data/stubs/inertia-react-ts/app/javascript/Components/ui/sidebar.tsx +719 -0
  82. data/stubs/inertia-react-ts/app/javascript/Components/ui/skeleton.tsx +13 -0
  83. data/stubs/inertia-react-ts/app/javascript/Components/ui/tooltip.tsx +55 -0
  84. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +19 -127
  85. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +2 -2
  86. data/stubs/inertia-react-ts/app/javascript/Layouts/SettingsLayout.tsx +57 -0
  87. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +6 -6
  88. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +17 -12
  89. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +14 -14
  90. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +10 -10
  91. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/VerifyEmail.tsx +2 -2
  92. data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +13 -8
  93. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Appearance.tsx +33 -0
  94. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.tsx +107 -0
  95. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.tsx +41 -0
  96. data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.tsx +12 -20
  97. data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.tsx +13 -21
  98. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Password.tsx +33 -0
  99. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Profile.tsx +35 -0
  100. data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +6 -1
  101. data/stubs/inertia-react-ts/app/javascript/hooks/use-initials.tsx +23 -0
  102. data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile-navigation.tsx +11 -0
  103. data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile.tsx +36 -0
  104. data/stubs/inertia-react-ts/app/javascript/lib/appearance.ts +22 -0
  105. data/stubs/inertia-react-ts/app/javascript/lib/utils.ts +6 -0
  106. data/stubs/inertia-react-ts/app/javascript/types/global.d.ts +2 -2
  107. data/stubs/inertia-react-ts/app/javascript/types/index.d.ts +14 -0
  108. data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +19 -1
  109. data/stubs/inertia-react-ts/components.json +21 -0
  110. data/stubs/inertia-react-ts/package.json +13 -0
  111. data/stubs/inertia-vue-ts/app/assets/tailwind/application.css +124 -0
  112. data/stubs/inertia-vue-ts/app/javascript/Components/AppLogo.vue +17 -0
  113. data/stubs/inertia-vue-ts/app/javascript/Components/AppShell.vue +12 -0
  114. data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebar.vue +65 -0
  115. data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebarHeader.vue +20 -0
  116. data/stubs/inertia-vue-ts/app/javascript/Components/Breadcrumbs.vue +32 -0
  117. data/stubs/inertia-vue-ts/app/javascript/Components/Heading.vue +15 -0
  118. data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +1 -1
  119. data/stubs/inertia-vue-ts/app/javascript/Components/NavFooter.vue +33 -0
  120. data/stubs/inertia-vue-ts/app/javascript/Components/NavMain.vue +32 -0
  121. data/stubs/inertia-vue-ts/app/javascript/Components/NavUser.vue +40 -0
  122. data/stubs/inertia-vue-ts/app/javascript/Components/UserInfo.vue +25 -0
  123. data/stubs/inertia-vue-ts/app/javascript/Components/UserMenuContent.vue +47 -0
  124. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/Avatar.vue +18 -0
  125. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarFallback.vue +21 -0
  126. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarImage.vue +16 -0
  127. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/index.ts +3 -0
  128. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/Breadcrumb.vue +17 -0
  129. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbEllipsis.vue +23 -0
  130. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
  131. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbLink.vue +21 -0
  132. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbList.vue +17 -0
  133. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
  134. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbSeparator.vue +22 -0
  135. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/index.ts +7 -0
  136. data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/Button.vue +31 -0
  137. data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/index.ts +34 -0
  138. data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/Checkbox.vue +35 -0
  139. data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/index.ts +1 -0
  140. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/Dialog.vue +15 -0
  141. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogClose.vue +12 -0
  142. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogContent.vue +52 -0
  143. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogDescription.vue +23 -0
  144. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogFooter.vue +25 -0
  145. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogHeader.vue +14 -0
  146. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogOverlay.vue +26 -0
  147. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTitle.vue +23 -0
  148. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTrigger.vue +12 -0
  149. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/index.ts +9 -0
  150. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenu.vue +15 -0
  151. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuContent.vue +37 -0
  152. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  153. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
  154. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  155. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  156. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  157. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/index.ts +7 -0
  158. data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/Input.vue +50 -0
  159. data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/index.ts +1 -0
  160. data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/Label.vue +26 -0
  161. data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/index.ts +1 -0
  162. data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/Separator.vue +29 -0
  163. data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/index.ts +1 -0
  164. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/Sheet.vue +19 -0
  165. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetClose.vue +15 -0
  166. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetContent.vue +62 -0
  167. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetDescription.vue +21 -0
  168. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetFooter.vue +16 -0
  169. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetHeader.vue +15 -0
  170. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetOverlay.vue +21 -0
  171. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTitle.vue +21 -0
  172. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTrigger.vue +15 -0
  173. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/index.ts +8 -0
  174. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/Sidebar.vue +96 -0
  175. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarContent.vue +18 -0
  176. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarFooter.vue +18 -0
  177. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroup.vue +18 -0
  178. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupAction.vue +27 -0
  179. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupContent.vue +18 -0
  180. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupLabel.vue +25 -0
  181. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarHeader.vue +18 -0
  182. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInput.vue +22 -0
  183. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInset.vue +21 -0
  184. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenu.vue +18 -0
  185. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuAction.vue +35 -0
  186. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuBadge.vue +26 -0
  187. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButton.vue +48 -0
  188. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
  189. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuItem.vue +18 -0
  190. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
  191. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSub.vue +22 -0
  192. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
  193. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
  194. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarProvider.vue +82 -0
  195. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarRail.vue +33 -0
  196. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarSeparator.vue +19 -0
  197. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarTrigger.vue +28 -0
  198. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/index.ts +60 -0
  199. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/utils.ts +19 -0
  200. data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/Skeleton.vue +17 -0
  201. data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/index.ts +1 -0
  202. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/Tooltip.vue +19 -0
  203. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipContent.vue +34 -0
  204. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipProvider.vue +14 -0
  205. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipTrigger.vue +15 -0
  206. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/index.ts +4 -0
  207. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +17 -147
  208. data/stubs/inertia-vue-ts/app/javascript/Layouts/SettingsLayout.vue +57 -0
  209. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +7 -7
  210. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +10 -12
  211. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +12 -14
  212. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +8 -10
  213. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/VerifyEmail.vue +3 -3
  214. data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +15 -10
  215. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Appearance.vue +33 -0
  216. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.vue +96 -0
  217. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.vue +42 -0
  218. data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.vue +12 -20
  219. data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.vue +12 -20
  220. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Password.vue +33 -0
  221. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Profile.vue +40 -0
  222. data/stubs/inertia-vue-ts/app/javascript/composables/useInitials.ts +29 -0
  223. data/stubs/inertia-vue-ts/app/javascript/lib/appearance.ts +22 -0
  224. data/stubs/inertia-vue-ts/app/javascript/lib/utils.ts +6 -0
  225. data/stubs/inertia-vue-ts/app/javascript/types/index.d.ts +14 -0
  226. data/stubs/inertia-vue-ts/app/javascript/types/vue-shims.d.ts +10 -0
  227. data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +19 -1
  228. data/stubs/inertia-vue-ts/components.json +20 -0
  229. data/stubs/inertia-vue-ts/package.json +8 -1
  230. data/stubs/inertia-vue-ts/vite.config.ts +25 -1
  231. metadata +174 -43
  232. data/stubs/hotwire/app/components/nav_link_component.rb +0 -15
  233. data/stubs/hotwire/app/components/responsive_nav_link_component.rb +0 -15
  234. data/stubs/hotwire/app/controllers/password_controller.rb +0 -13
  235. data/stubs/hotwire/app/views/layouts/_navigation.html.erb +0 -82
  236. data/stubs/hotwire/app/views/profile/edit.html.erb +0 -24
  237. data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +0 -14
  238. data/stubs/inertia-common/app/controllers/password_controller.rb +0 -13
  239. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +0 -11
  240. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +0 -20
  241. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +0 -100
  242. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +0 -14
  243. data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +0 -66
  244. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +0 -21
  245. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +0 -20
  246. data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +0 -21
  247. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +0 -22
  248. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +0 -32
  249. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +0 -32
  250. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +0 -102
  251. data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +0 -29
  252. data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +0 -7
  253. data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +0 -75
  254. data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +0 -16
  255. data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +0 -12
  256. data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +0 -109
  257. data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +0 -21
  258. data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +0 -7
  259. data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +0 -21
  260. data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +0 -19
  261. data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +0 -23
  262. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +0 -38
  263. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +0 -99
@@ -1,152 +1,22 @@
1
1
  <script setup lang="ts">
2
- import { ref } from 'vue'
3
- import ApplicationLogo from '@/Components/ApplicationLogo.vue'
4
- import Dropdown from '@/Components/Dropdown.vue'
5
- import DropdownLink from '@/Components/DropdownLink.vue'
6
- import NavLink from '@/Components/NavLink.vue'
7
- import ResponsiveNavLink from '@/Components/ResponsiveNavLink.vue'
8
- import { Link } from '@inertiajs/vue3'
9
- import { dashboard_path, logout_path, profile_edit_path } from '@/routes'
10
-
11
- const showingNavigationDropdown = ref(false)
12
-
13
- const { pathname = '' } = typeof window !== 'undefined' ? window.location : {}
2
+ import AppShell from '@/Components/AppShell.vue'
3
+ import AppSidebar from '@/Components/AppSidebar.vue'
4
+ import AppSidebarHeader from '@/Components/AppSidebarHeader.vue'
5
+ import { SidebarInset } from '@/Components/ui/sidebar'
6
+ import { BreadcrumbItem } from '@/types'
7
+
8
+ withDefaults(defineProps<{ breadcrumbs?: BreadcrumbItem[] }>(), {
9
+ breadcrumbs: () => [],
10
+ })
14
11
  </script>
15
12
 
16
13
  <template>
17
- <div>
18
- <div class="min-h-screen bg-gray-100 dark:bg-gray-900">
19
- <nav class="bg-white dark:bg-gray-800 border-b border-gray-100 dark:border-gray-700">
20
- <!-- Primary Navigation Menu -->
21
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
22
- <div class="flex justify-between h-16">
23
- <div class="flex">
24
- <!-- Logo -->
25
- <div class="shrink-0 flex items-center">
26
- <Link href="/">
27
- <ApplicationLogo class="block h-9 w-auto fill-current text-red-800 dark:text-red-200" />
28
- </Link>
29
- </div>
30
-
31
- <!-- Navigation Links -->
32
- <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
33
- <NavLink :href="dashboard_path()" :active="pathname.match(/dashboard/) != null"> Dashboard </NavLink>
34
- </div>
35
- </div>
36
-
37
- <div class="hidden sm:flex sm:items-center sm:ms-6">
38
- <!-- Settings Dropdown -->
39
- <div class="ms-3 relative">
40
- <Dropdown align="right" width="48">
41
- <template #trigger>
42
- <span class="inline-flex rounded-md">
43
- <button
44
- type="button"
45
- class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-hidden transition ease-in-out duration-150"
46
- >
47
- {{ $page.props.auth.user.name }}
48
-
49
- <svg
50
- class="ms-2 -me-0.5 h-4 w-4"
51
- xmlns="http://www.w3.org/2000/svg"
52
- viewBox="0 0 20 20"
53
- fill="currentColor"
54
- >
55
- <path
56
- fill-rule="evenodd"
57
- d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
58
- clip-rule="evenodd"
59
- />
60
- </svg>
61
- </button>
62
- </span>
63
- </template>
64
-
65
- <template #content>
66
- <DropdownLink :href="profile_edit_path()"> Profile </DropdownLink>
67
- <DropdownLink :href="logout_path()" method="post" as="button"> Log Out </DropdownLink>
68
- </template>
69
- </Dropdown>
70
- </div>
71
- </div>
72
-
73
- <!-- Hamburger -->
74
- <div class="-me-2 flex items-center sm:hidden">
75
- <button
76
- @click="showingNavigationDropdown = !showingNavigationDropdown"
77
- class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-900 focus:outline-hidden focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-500 dark:focus:text-gray-400 transition duration-150 ease-in-out"
78
- >
79
- <svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
80
- <path
81
- :class="{
82
- hidden: showingNavigationDropdown,
83
- 'inline-flex': !showingNavigationDropdown,
84
- }"
85
- stroke-linecap="round"
86
- stroke-linejoin="round"
87
- stroke-width="2"
88
- d="M4 6h16M4 12h16M4 18h16"
89
- />
90
- <path
91
- :class="{
92
- hidden: !showingNavigationDropdown,
93
- 'inline-flex': showingNavigationDropdown,
94
- }"
95
- stroke-linecap="round"
96
- stroke-linejoin="round"
97
- stroke-width="2"
98
- d="M6 18L18 6M6 6l12 12"
99
- />
100
- </svg>
101
- </button>
102
- </div>
103
- </div>
104
- </div>
105
-
106
- <!-- Responsive Navigation Menu -->
107
- <div
108
- :class="{
109
- block: showingNavigationDropdown,
110
- hidden: !showingNavigationDropdown,
111
- }"
112
- class="sm:hidden"
113
- >
114
- <div class="pt-2 pb-3 space-y-1">
115
- <ResponsiveNavLink :href="dashboard_path()" :active="pathname.match(/dashboard/) != null">
116
- Dashboard
117
- </ResponsiveNavLink>
118
- </div>
119
-
120
- <!-- Responsive Settings Options -->
121
- <div class="pt-4 pb-1 border-t border-gray-200 dark:border-gray-600">
122
- <div class="px-4">
123
- <div class="font-medium text-base text-gray-800 dark:text-gray-200">
124
- {{ $page.props.auth.user.name }}
125
- </div>
126
- <div class="font-medium text-sm text-gray-500">
127
- {{ $page.props.auth.user.email }}
128
- </div>
129
- </div>
130
-
131
- <div class="mt-3 space-y-1">
132
- <ResponsiveNavLink :href="profile_edit_path()"> Profile </ResponsiveNavLink>
133
- <ResponsiveNavLink :href="logout_path()" method="post" as="button"> Log Out </ResponsiveNavLink>
134
- </div>
135
- </div>
136
- </div>
137
- </nav>
138
-
139
- <!-- Page Heading -->
140
- <header class="bg-white dark:bg-gray-800 shadow-sm" v-if="$slots.header">
141
- <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
142
- <slot name="header" />
143
- </div>
144
- </header>
145
-
146
- <!-- Page Content -->
147
- <main>
148
- <slot />
149
- </main>
150
- </div>
151
- </div>
14
+ <AppShell>
15
+ <AppSidebar />
16
+
17
+ <SidebarInset class="min-w-0 overflow-x-clip">
18
+ <AppSidebarHeader :breadcrumbs="breadcrumbs" />
19
+ <slot />
20
+ </SidebarInset>
21
+ </AppShell>
152
22
  </template>
@@ -0,0 +1,57 @@
1
+ <script setup lang="ts">
2
+ import { Link, usePage } from '@inertiajs/vue3'
3
+ import Heading from '@/Components/Heading.vue'
4
+ import { Button } from '@/Components/ui/button'
5
+ import { Separator } from '@/Components/ui/separator'
6
+ import { cn } from '@/lib/utils'
7
+ import { appearance_edit_path, password_edit_path, profile_edit_path } from '@/routes'
8
+ import { NavItem } from '@/types'
9
+
10
+ const sidebarNavItems: NavItem[] = [
11
+ {
12
+ title: 'Profile',
13
+ href: profile_edit_path(),
14
+ },
15
+ {
16
+ title: 'Password',
17
+ href: password_edit_path(),
18
+ },
19
+ {
20
+ title: 'Appearance',
21
+ href: appearance_edit_path(),
22
+ },
23
+ ]
24
+
25
+ const page = usePage()
26
+ </script>
27
+
28
+ <template>
29
+ <div class="px-4 py-6">
30
+ <Heading title="Settings" description="Manage your profile and account settings" />
31
+
32
+ <div class="flex flex-col lg:flex-row lg:space-x-12">
33
+ <aside class="w-full max-w-xl lg:w-48">
34
+ <nav class="flex flex-col space-y-1 space-x-0" aria-label="Settings">
35
+ <Button
36
+ v-for="item in sidebarNavItems"
37
+ :key="item.href"
38
+ size="sm"
39
+ variant="ghost"
40
+ as-child
41
+ :class="cn('w-full justify-start', { 'bg-muted': page.url.startsWith(item.href) })"
42
+ >
43
+ <Link :href="item.href">{{ item.title }}</Link>
44
+ </Button>
45
+ </nav>
46
+ </aside>
47
+
48
+ <Separator class="my-6 lg:hidden" />
49
+
50
+ <div class="flex-1 md:max-w-2xl">
51
+ <section class="max-w-xl space-y-12">
52
+ <slot />
53
+ </section>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </template>
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import GuestLayout from '@/Layouts/GuestLayout.vue'
3
+ import { Button } from '@/Components/ui/button'
4
+ import { Input } from '@/Components/ui/input'
5
+ import { Label } from '@/Components/ui/label'
3
6
  import InputError from '@/Components/InputError.vue'
4
- import InputLabel from '@/Components/InputLabel.vue'
5
- import PrimaryButton from '@/Components/PrimaryButton.vue'
6
- import TextInput from '@/Components/TextInput.vue'
7
7
  import { Head, useForm } from '@inertiajs/vue3'
8
8
  import { password_email_path } from '@/routes'
9
9
 
@@ -35,9 +35,9 @@ const submit = () => {
35
35
 
36
36
  <form @submit.prevent="submit">
37
37
  <div>
38
- <InputLabel for="email" value="Email" />
38
+ <Label for="email">Email</Label>
39
39
 
40
- <TextInput
40
+ <Input
41
41
  id="email"
42
42
  type="email"
43
43
  class="mt-1 block w-full"
@@ -51,9 +51,9 @@ const submit = () => {
51
51
  </div>
52
52
 
53
53
  <div class="flex items-center justify-end mt-4">
54
- <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
54
+ <Button :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
55
55
  Email Password Reset Link
56
- </PrimaryButton>
56
+ </Button>
57
57
  </div>
58
58
  </form>
59
59
  </GuestLayout>
@@ -1,10 +1,10 @@
1
1
  <script setup lang="ts">
2
- import Checkbox from '@/Components/Checkbox.vue'
2
+ import { Button } from '@/Components/ui/button'
3
+ import { Input } from '@/Components/ui/input'
4
+ import { Label } from '@/Components/ui/label'
5
+ import { Checkbox } from '@/Components/ui/checkbox'
3
6
  import GuestLayout from '@/Layouts/GuestLayout.vue'
4
7
  import InputError from '@/Components/InputError.vue'
5
- import InputLabel from '@/Components/InputLabel.vue'
6
- import PrimaryButton from '@/Components/PrimaryButton.vue'
7
- import TextInput from '@/Components/TextInput.vue'
8
8
  import { Head, Link, useForm } from '@inertiajs/vue3'
9
9
  import { login_path, password_request_path } from '@/routes'
10
10
 
@@ -37,9 +37,9 @@ const submit = () => {
37
37
 
38
38
  <form @submit.prevent="submit">
39
39
  <div>
40
- <InputLabel for="email" value="Email" />
40
+ <Label for="email">Email</Label>
41
41
 
42
- <TextInput
42
+ <Input
43
43
  id="email"
44
44
  type="email"
45
45
  class="mt-1 block w-full"
@@ -53,9 +53,9 @@ const submit = () => {
53
53
  </div>
54
54
 
55
55
  <div class="mt-4">
56
- <InputLabel for="password" value="Password" />
56
+ <Label for="password">Password</Label>
57
57
 
58
- <TextInput
58
+ <Input
59
59
  id="password"
60
60
  type="password"
61
61
  class="mt-1 block w-full"
@@ -69,7 +69,7 @@ const submit = () => {
69
69
 
70
70
  <div class="block mt-4">
71
71
  <label class="flex items-center">
72
- <Checkbox name="remember" v-model:checked="form.remember" />
72
+ <Checkbox id="remember" name="remember" v-model="form.remember" />
73
73
  <span class="ms-2 text-sm text-gray-600 dark:text-gray-400">Remember me</span>
74
74
  </label>
75
75
  </div>
@@ -82,9 +82,7 @@ const submit = () => {
82
82
  Forgot your password?
83
83
  </Link>
84
84
 
85
- <PrimaryButton class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
86
- Log in
87
- </PrimaryButton>
85
+ <Button class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing"> Log in </Button>
88
86
  </div>
89
87
  </form>
90
88
  </GuestLayout>
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import GuestLayout from '@/Layouts/GuestLayout.vue'
3
+ import { Button } from '@/Components/ui/button'
4
+ import { Input } from '@/Components/ui/input'
5
+ import { Label } from '@/Components/ui/label'
3
6
  import InputError from '@/Components/InputError.vue'
4
- import InputLabel from '@/Components/InputLabel.vue'
5
- import PrimaryButton from '@/Components/PrimaryButton.vue'
6
- import TextInput from '@/Components/TextInput.vue'
7
7
  import { Head, Link, useForm } from '@inertiajs/vue3'
8
8
  import { login_path, register_path } from '@/routes'
9
9
 
@@ -29,9 +29,9 @@ const submit = () => {
29
29
 
30
30
  <form @submit.prevent="submit">
31
31
  <div>
32
- <InputLabel for="name" value="Name" />
32
+ <Label for="name">Name</Label>
33
33
 
34
- <TextInput
34
+ <Input
35
35
  id="name"
36
36
  type="text"
37
37
  class="mt-1 block w-full"
@@ -45,9 +45,9 @@ const submit = () => {
45
45
  </div>
46
46
 
47
47
  <div class="mt-4">
48
- <InputLabel for="email" value="Email" />
48
+ <Label for="email">Email</Label>
49
49
 
50
- <TextInput
50
+ <Input
51
51
  id="email"
52
52
  type="email"
53
53
  class="mt-1 block w-full"
@@ -60,9 +60,9 @@ const submit = () => {
60
60
  </div>
61
61
 
62
62
  <div class="mt-4">
63
- <InputLabel for="password" value="Password" />
63
+ <Label for="password">Password</Label>
64
64
 
65
- <TextInput
65
+ <Input
66
66
  id="password"
67
67
  type="password"
68
68
  class="mt-1 block w-full"
@@ -75,9 +75,9 @@ const submit = () => {
75
75
  </div>
76
76
 
77
77
  <div class="mt-4">
78
- <InputLabel for="password_confirmation" value="Confirm Password" />
78
+ <Label for="password_confirmation">Confirm Password</Label>
79
79
 
80
- <TextInput
80
+ <Input
81
81
  id="password_confirmation"
82
82
  type="password"
83
83
  class="mt-1 block w-full"
@@ -97,9 +97,7 @@ const submit = () => {
97
97
  Already registered?
98
98
  </Link>
99
99
 
100
- <PrimaryButton class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
101
- Register
102
- </PrimaryButton>
100
+ <Button class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing"> Register </Button>
103
101
  </div>
104
102
  </form>
105
103
  </GuestLayout>
@@ -1,9 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import GuestLayout from '@/Layouts/GuestLayout.vue'
3
+ import { Button } from '@/Components/ui/button'
4
+ import { Input } from '@/Components/ui/input'
5
+ import { Label } from '@/Components/ui/label'
3
6
  import InputError from '@/Components/InputError.vue'
4
- import InputLabel from '@/Components/InputLabel.vue'
5
- import PrimaryButton from '@/Components/PrimaryButton.vue'
6
- import TextInput from '@/Components/TextInput.vue'
7
7
  import { Head, useForm } from '@inertiajs/vue3'
8
8
  import { password_store_path } from '@/routes'
9
9
 
@@ -32,9 +32,9 @@ const submit = () => {
32
32
 
33
33
  <form @submit.prevent="submit">
34
34
  <div>
35
- <InputLabel for="password" value="Password" />
35
+ <Label for="password">Password</Label>
36
36
 
37
- <TextInput
37
+ <Input
38
38
  id="password"
39
39
  type="password"
40
40
  class="mt-1 block w-full"
@@ -48,9 +48,9 @@ const submit = () => {
48
48
  </div>
49
49
 
50
50
  <div class="mt-4">
51
- <InputLabel for="password_confirmation" value="Confirm Password" />
51
+ <Label for="password_confirmation">Confirm Password</Label>
52
52
 
53
- <TextInput
53
+ <Input
54
54
  id="password_confirmation"
55
55
  type="password"
56
56
  class="mt-1 block w-full"
@@ -63,9 +63,7 @@ const submit = () => {
63
63
  </div>
64
64
 
65
65
  <div class="flex items-center justify-end mt-4">
66
- <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
67
- Reset Password
68
- </PrimaryButton>
66
+ <Button :class="{ 'opacity-25': form.processing }" :disabled="form.processing"> Reset Password </Button>
69
67
  </div>
70
68
  </form>
71
69
  </GuestLayout>
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue'
3
+ import { Button } from '@/Components/ui/button'
3
4
  import GuestLayout from '@/Layouts/GuestLayout.vue'
4
- import PrimaryButton from '@/Components/PrimaryButton.vue'
5
5
  import { Head, Link, useForm } from '@inertiajs/vue3'
6
6
  import { logout_path, verification_send_path } from '@/routes'
7
7
 
@@ -33,9 +33,9 @@ const verificationLinkSent = computed(() => props.status === 'verification-link-
33
33
 
34
34
  <form @submit.prevent="submit">
35
35
  <div class="mt-4 flex items-center justify-between">
36
- <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
36
+ <Button :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
37
37
  Resend Verification Email
38
- </PrimaryButton>
38
+ </Button>
39
39
 
40
40
  <Link
41
41
  :href="logout_path()"
@@ -1,21 +1,26 @@
1
1
  <script setup lang="ts">
2
2
  import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
3
3
  import { Head } from '@inertiajs/vue3'
4
+ import { dashboard_path } from '@/routes'
5
+ import { BreadcrumbItem } from '@/types'
6
+
7
+ const breadcrumbs: BreadcrumbItem[] = [
8
+ {
9
+ title: 'Dashboard',
10
+ href: dashboard_path(),
11
+ },
12
+ ]
4
13
  </script>
5
14
 
6
15
  <template>
7
16
  <Head title="Dashboard" />
8
17
 
9
- <AuthenticatedLayout>
10
- <template #header>
11
- <h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">Dashboard</h2>
12
- </template>
13
-
14
- <div class="py-12">
15
- <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
16
- <div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xs sm:rounded-lg">
17
- <div class="p-6 text-gray-900 dark:text-gray-100">You're logged in!</div>
18
- </div>
18
+ <AuthenticatedLayout :breadcrumbs="breadcrumbs">
19
+ <div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
20
+ <div
21
+ class="relative min-h-[60vh] flex-1 overflow-hidden rounded-xl border border-sidebar-border/70 p-6 dark:border-sidebar-border"
22
+ >
23
+ You're logged in!
19
24
  </div>
20
25
  </div>
21
26
  </AuthenticatedLayout>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import { Head } from '@inertiajs/vue3'
3
+ import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
4
+ import SettingsLayout from '@/Layouts/SettingsLayout.vue'
5
+ import Heading from '@/Components/Heading.vue'
6
+ import UpdateAppearanceForm from './Partials/UpdateAppearanceForm.vue'
7
+ import { appearance_edit_path } from '@/routes'
8
+ import { BreadcrumbItem } from '@/types'
9
+
10
+ const breadcrumbs: BreadcrumbItem[] = [
11
+ {
12
+ title: 'Appearance settings',
13
+ href: appearance_edit_path(),
14
+ },
15
+ ]
16
+ </script>
17
+
18
+ <template>
19
+ <Head title="Appearance settings" />
20
+
21
+ <AuthenticatedLayout :breadcrumbs="breadcrumbs">
22
+ <SettingsLayout>
23
+ <div class="space-y-6">
24
+ <Heading
25
+ variant="small"
26
+ title="Appearance settings"
27
+ description="Update the appearance settings for your account"
28
+ />
29
+ <UpdateAppearanceForm />
30
+ </div>
31
+ </SettingsLayout>
32
+ </AuthenticatedLayout>
33
+ </template>
@@ -0,0 +1,96 @@
1
+ <script setup lang="ts">
2
+ import InputError from '@/Components/InputError.vue'
3
+ import { Button } from '@/Components/ui/button'
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogFooter,
9
+ DialogHeader,
10
+ DialogTitle,
11
+ } from '@/Components/ui/dialog'
12
+ import { Input } from '@/Components/ui/input'
13
+ import { Label } from '@/Components/ui/label'
14
+ import { useForm } from '@inertiajs/vue3'
15
+ import { nextTick, ref } from 'vue'
16
+ import { profile_destroy_path } from '@/routes'
17
+
18
+ const confirmingUserDeletion = ref(false)
19
+ const passwordInput = ref<HTMLInputElement | null>(null)
20
+
21
+ const form = useForm({
22
+ password: '',
23
+ })
24
+
25
+ const confirmUserDeletion = () => {
26
+ confirmingUserDeletion.value = true
27
+
28
+ nextTick(() => passwordInput.value?.focus())
29
+ }
30
+
31
+ const deleteUser = () => {
32
+ form.delete(profile_destroy_path(), {
33
+ preserveScroll: true,
34
+ onSuccess: () => closeModal(),
35
+ onError: () => passwordInput.value?.focus(),
36
+ onFinish: () => {
37
+ form.reset()
38
+ },
39
+ })
40
+ }
41
+
42
+ const closeModal = () => {
43
+ confirmingUserDeletion.value = false
44
+
45
+ form.clearErrors()
46
+ form.reset()
47
+ }
48
+ </script>
49
+
50
+ <template>
51
+ <section class="space-y-6">
52
+ <Button variant="destructive" @click="confirmUserDeletion">Delete Account</Button>
53
+
54
+ <Dialog v-model:open="confirmingUserDeletion">
55
+ <DialogContent>
56
+ <DialogHeader>
57
+ <DialogTitle>Are you sure you want to delete your account?</DialogTitle>
58
+
59
+ <DialogDescription>
60
+ Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your
61
+ password to confirm you would like to permanently delete your account.
62
+ </DialogDescription>
63
+ </DialogHeader>
64
+
65
+ <div class="mt-6">
66
+ <Label for="password" class="sr-only">Password</Label>
67
+
68
+ <Input
69
+ id="password"
70
+ ref="passwordInput"
71
+ v-model="form.password"
72
+ type="password"
73
+ class="mt-1 block w-3/4"
74
+ placeholder="Password"
75
+ @keyup.enter="deleteUser"
76
+ />
77
+
78
+ <InputError :message="form.errors.password" class="mt-2" />
79
+ </div>
80
+
81
+ <DialogFooter>
82
+ <Button variant="outline" @click="closeModal"> Cancel </Button>
83
+
84
+ <Button
85
+ variant="destructive"
86
+ :class="{ 'opacity-25': form.processing }"
87
+ :disabled="form.processing"
88
+ @click="deleteUser"
89
+ >
90
+ Delete Account
91
+ </Button>
92
+ </DialogFooter>
93
+ </DialogContent>
94
+ </Dialog>
95
+ </section>
96
+ </template>