kaze 1.4.0 → 2.0.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -1
- data/README.md +1 -1
- data/lib/kaze/commands/app/base_stack.rb +12 -2
- data/lib/kaze/commands/app/hotwire_stack.rb +3 -1
- data/lib/kaze/commands/app/inertia_react_stack.rb +6 -2
- data/lib/kaze/commands/app/inertia_vue_stack.rb +6 -2
- data/lib/kaze/commands/app.rb +9 -2
- data/lib/kaze/version.rb +1 -1
- data/stubs/default/config/routes.rb +11 -4
- data/stubs/default/test/integration/appearance_test.rb +11 -0
- data/stubs/default/test/integration/password_update_test.rb +9 -1
- data/stubs/hotwire/app/assets/tailwind/application.css +119 -1
- data/stubs/hotwire/app/components/breadcrumbs_component.rb +32 -0
- data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
- data/stubs/hotwire/app/components/dropdown_component.html.erb +2 -2
- data/stubs/hotwire/app/components/dropdown_component.rb +5 -1
- data/stubs/hotwire/app/components/dropdown_link_component.rb +1 -1
- data/stubs/hotwire/app/components/heading_component.rb +19 -0
- data/stubs/hotwire/app/components/icon_component.rb +30 -0
- data/stubs/hotwire/app/components/input_error_component.rb +1 -1
- data/stubs/hotwire/app/components/input_label_component.rb +3 -3
- data/stubs/hotwire/app/components/modal_component.html.erb +2 -2
- 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/components/sidebar_menu_button_component.rb +25 -0
- data/stubs/hotwire/app/components/text_input_component.rb +1 -1
- data/stubs/hotwire/app/components/user_avatar_component.rb +27 -0
- data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
- data/stubs/hotwire/app/controllers/concerns/sidebar_state.rb +14 -0
- data/stubs/hotwire/app/controllers/settings/appearance_controller.rb +7 -0
- data/stubs/hotwire/app/controllers/settings/password_controller.rb +19 -0
- data/stubs/hotwire/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +3 -4
- data/stubs/hotwire/app/views/auth/login.html.erb +1 -1
- data/stubs/hotwire/app/views/dashboard/index.html.erb +6 -11
- data/stubs/hotwire/app/views/layouts/_settings.html.erb +26 -0
- data/stubs/hotwire/app/views/layouts/_sidebar.html.erb +56 -0
- data/stubs/hotwire/app/views/layouts/_sidebar_header.html.erb +11 -0
- data/stubs/hotwire/app/views/layouts/_sidebar_user.html.erb +34 -0
- data/stubs/hotwire/app/views/layouts/application.html.erb +24 -15
- data/stubs/hotwire/app/views/settings/appearance/_update_appearance_form.html.erb +28 -0
- data/stubs/hotwire/app/views/settings/appearance/edit.html.erb +10 -0
- data/stubs/hotwire/app/views/{profile/partials → settings/password}/_update_password_form.html.erb +2 -10
- data/stubs/hotwire/app/views/settings/password/edit.html.erb +10 -0
- data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_confirm_user_deletion_modal.html.erb +2 -2
- data/stubs/hotwire/app/views/settings/profile/_delete_user_form.html.erb +6 -0
- data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_update_profile_information_form.html.erb +4 -12
- data/stubs/hotwire/app/views/{profile → settings/profile}/destroy.turbo_stream.erb +1 -1
- data/stubs/hotwire/app/views/settings/profile/edit.html.erb +14 -0
- data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +4 -1
- data/stubs/inertia-common/app/controllers/settings/appearance_controller.rb +7 -0
- data/stubs/inertia-common/app/controllers/settings/password_controller.rb +17 -0
- data/stubs/inertia-common/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +2 -2
- data/stubs/inertia-common/test/integration/appearance_test.rb +11 -0
- data/stubs/inertia-common/test/integration/password_update_test.rb +10 -2
- data/stubs/inertia-react-ts/app/assets/tailwind/application.css +120 -1
- data/stubs/inertia-react-ts/app/javascript/Components/AppLogo.tsx +17 -0
- data/stubs/inertia-react-ts/app/javascript/Components/AppShell.tsx +9 -0
- data/stubs/inertia-react-ts/app/javascript/Components/AppSidebar.tsx +65 -0
- data/stubs/inertia-react-ts/app/javascript/Components/AppSidebarHeader.tsx +14 -0
- data/stubs/inertia-react-ts/app/javascript/Components/Breadcrumbs.tsx +43 -0
- data/stubs/inertia-react-ts/app/javascript/Components/Heading.tsx +19 -0
- data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Components/NavFooter.tsx +32 -0
- data/stubs/inertia-react-ts/app/javascript/Components/NavMain.tsx +32 -0
- data/stubs/inertia-react-ts/app/javascript/Components/NavUser.tsx +39 -0
- data/stubs/inertia-react-ts/app/javascript/Components/UserInfo.tsx +23 -0
- data/stubs/inertia-react-ts/app/javascript/Components/UserMenuContent.tsx +57 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/avatar.tsx +51 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/breadcrumb.tsx +109 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/button.tsx +49 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/checkbox.tsx +27 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/dialog.tsx +109 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/dropdown-menu.tsx +217 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/input.tsx +21 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/label.tsx +19 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/separator.tsx +26 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/sheet.tsx +137 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/sidebar.tsx +719 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/skeleton.tsx +13 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ui/tooltip.tsx +55 -0
- data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +19 -127
- data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +1 -1
- data/stubs/inertia-react-ts/app/javascript/Layouts/SettingsLayout.tsx +57 -0
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +6 -6
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +17 -12
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +14 -14
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +10 -10
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/VerifyEmail.tsx +2 -2
- data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +13 -8
- data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Appearance.tsx +33 -0
- data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.tsx +107 -0
- data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.tsx +41 -0
- data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.tsx +12 -20
- data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.tsx +13 -21
- data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Password.tsx +33 -0
- data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Profile.tsx +35 -0
- data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +6 -1
- data/stubs/inertia-react-ts/app/javascript/hooks/use-initials.tsx +23 -0
- data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile-navigation.tsx +11 -0
- data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile.tsx +36 -0
- data/stubs/inertia-react-ts/app/javascript/lib/appearance.ts +1 -2
- data/stubs/inertia-react-ts/app/javascript/lib/utils.ts +6 -0
- data/stubs/inertia-react-ts/app/javascript/types/global.d.ts +2 -2
- data/stubs/inertia-react-ts/app/javascript/types/index.d.ts +14 -0
- data/stubs/inertia-react-ts/components.json +21 -0
- data/stubs/inertia-react-ts/package.json +13 -0
- data/stubs/inertia-vue-ts/app/assets/tailwind/application.css +120 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/AppLogo.vue +17 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/AppShell.vue +12 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebar.vue +65 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebarHeader.vue +20 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/Breadcrumbs.vue +32 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/Heading.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +1 -1
- data/stubs/inertia-vue-ts/app/javascript/Components/NavFooter.vue +33 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/NavMain.vue +32 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/NavUser.vue +40 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/UserInfo.vue +25 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/UserMenuContent.vue +47 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/Avatar.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarFallback.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarImage.vue +16 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/index.ts +3 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/Breadcrumb.vue +17 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbEllipsis.vue +23 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbLink.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbList.vue +17 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbSeparator.vue +22 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/index.ts +7 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/Button.vue +31 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/index.ts +34 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/Checkbox.vue +35 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/index.ts +1 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/Dialog.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogClose.vue +12 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogContent.vue +52 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogDescription.vue +23 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogFooter.vue +25 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogHeader.vue +14 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogOverlay.vue +26 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTitle.vue +23 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTrigger.vue +12 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/index.ts +9 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenu.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuContent.vue +37 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuTrigger.vue +14 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/index.ts +7 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/Input.vue +50 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/index.ts +1 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/Label.vue +26 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/index.ts +1 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/Separator.vue +29 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/index.ts +1 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/Sheet.vue +19 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetClose.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetContent.vue +62 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetDescription.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetFooter.vue +16 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetHeader.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetOverlay.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTitle.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTrigger.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/index.ts +8 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/Sidebar.vue +96 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarContent.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarFooter.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroup.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupAction.vue +27 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupContent.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupLabel.vue +25 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarHeader.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInput.vue +22 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInset.vue +21 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenu.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuAction.vue +35 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuBadge.vue +26 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButton.vue +48 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuItem.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSub.vue +22 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarProvider.vue +82 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarRail.vue +33 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarSeparator.vue +19 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarTrigger.vue +28 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/index.ts +60 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/utils.ts +19 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/Skeleton.vue +17 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/index.ts +1 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/Tooltip.vue +19 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipContent.vue +34 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipProvider.vue +14 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipTrigger.vue +15 -0
- data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/index.ts +4 -0
- data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +17 -147
- data/stubs/inertia-vue-ts/app/javascript/Layouts/SettingsLayout.vue +57 -0
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +7 -7
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +10 -12
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +12 -14
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +8 -10
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/VerifyEmail.vue +3 -3
- data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +15 -10
- data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Appearance.vue +33 -0
- data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.vue +96 -0
- data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.vue +42 -0
- data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.vue +12 -20
- data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.vue +12 -20
- data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Password.vue +33 -0
- data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Profile.vue +40 -0
- data/stubs/inertia-vue-ts/app/javascript/composables/useInitials.ts +29 -0
- data/stubs/inertia-vue-ts/app/javascript/lib/appearance.ts +1 -2
- data/stubs/inertia-vue-ts/app/javascript/lib/utils.ts +6 -0
- data/stubs/inertia-vue-ts/app/javascript/types/index.d.ts +14 -0
- data/stubs/inertia-vue-ts/app/javascript/types/vue-shims.d.ts +10 -0
- data/stubs/inertia-vue-ts/components.json +20 -0
- data/stubs/inertia-vue-ts/package.json +8 -1
- data/stubs/inertia-vue-ts/vite.config.ts +25 -1
- metadata +171 -46
- data/stubs/hotwire/app/components/nav_link_component.rb +0 -15
- data/stubs/hotwire/app/components/responsive_nav_link_component.rb +0 -15
- data/stubs/hotwire/app/controllers/password_controller.rb +0 -13
- data/stubs/hotwire/app/views/layouts/_navigation.html.erb +0 -82
- data/stubs/hotwire/app/views/profile/edit.html.erb +0 -29
- data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +0 -14
- data/stubs/hotwire/app/views/profile/partials/_update_appearance_form.html.erb +0 -39
- data/stubs/inertia-common/app/controllers/password_controller.rb +0 -13
- data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +0 -11
- data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +0 -20
- data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +0 -100
- data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +0 -14
- data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +0 -66
- data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +0 -21
- data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +0 -20
- data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +0 -21
- data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +0 -22
- data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +0 -32
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +0 -37
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +0 -102
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateAppearanceForm.tsx +0 -47
- data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +0 -29
- data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +0 -7
- data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +0 -75
- data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +0 -16
- data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +0 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +0 -109
- data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +0 -21
- data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +0 -7
- data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +0 -21
- data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +0 -19
- data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +0 -23
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +0 -43
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +0 -99
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateAppearanceForm.vue +0 -47
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, type Component } from 'vue'
|
|
3
|
+
import { Monitor, Moon, Sun } from '@lucide/vue'
|
|
4
|
+
import { getAppearance, setAppearance, type Appearance } from '@/lib/appearance'
|
|
5
|
+
import { cn } from '@/lib/utils'
|
|
6
|
+
|
|
7
|
+
const options: { value: Appearance; icon: Component; label: string }[] = [
|
|
8
|
+
{ value: 'light', icon: Sun, label: 'Light' },
|
|
9
|
+
{ value: 'dark', icon: Moon, label: 'Dark' },
|
|
10
|
+
{ value: 'system', icon: Monitor, label: 'System' },
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const appearance = ref<Appearance>(getAppearance())
|
|
14
|
+
|
|
15
|
+
const select = (value: Appearance) => {
|
|
16
|
+
appearance.value = value
|
|
17
|
+
setAppearance(value)
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<div class="inline-flex gap-1 rounded-lg bg-neutral-100 p-1 dark:bg-neutral-800">
|
|
23
|
+
<button
|
|
24
|
+
v-for="option in options"
|
|
25
|
+
:key="option.value"
|
|
26
|
+
type="button"
|
|
27
|
+
:aria-pressed="appearance === option.value"
|
|
28
|
+
:class="
|
|
29
|
+
cn(
|
|
30
|
+
'flex items-center rounded-md px-3.5 py-1.5 transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
31
|
+
appearance === option.value
|
|
32
|
+
? 'bg-white shadow-xs dark:bg-neutral-700 dark:text-neutral-100'
|
|
33
|
+
: 'text-neutral-500 hover:bg-neutral-200/60 hover:text-black dark:text-neutral-400 dark:hover:bg-neutral-700/60',
|
|
34
|
+
)
|
|
35
|
+
"
|
|
36
|
+
@click="select(option.value)"
|
|
37
|
+
>
|
|
38
|
+
<component :is="option.icon" class="-ml-1 h-4 w-4" />
|
|
39
|
+
<span class="ml-1.5 text-sm">{{ option.label }}</span>
|
|
40
|
+
</button>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.vue
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import InputError from '@/Components/InputError.vue'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import { Button } from '@/Components/ui/button'
|
|
4
|
+
import { Input } from '@/Components/ui/input'
|
|
5
|
+
import { Label } from '@/Components/ui/label'
|
|
6
6
|
import { useForm } from '@inertiajs/vue3'
|
|
7
7
|
import { ref } from 'vue'
|
|
8
8
|
import { password_update_path } from '@/routes'
|
|
@@ -38,19 +38,11 @@ const updatePassword = () => {
|
|
|
38
38
|
|
|
39
39
|
<template>
|
|
40
40
|
<section>
|
|
41
|
-
<
|
|
42
|
-
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">Update Password</h2>
|
|
43
|
-
|
|
44
|
-
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
|
45
|
-
Ensure your account is using a long, random password to stay secure.
|
|
46
|
-
</p>
|
|
47
|
-
</header>
|
|
48
|
-
|
|
49
|
-
<form @submit.prevent="updatePassword" class="mt-6 space-y-6">
|
|
41
|
+
<form @submit.prevent="updatePassword" class="space-y-6">
|
|
50
42
|
<div>
|
|
51
|
-
<
|
|
43
|
+
<Label for="current_password">Current Password</Label>
|
|
52
44
|
|
|
53
|
-
<
|
|
45
|
+
<Input
|
|
54
46
|
id="current_password"
|
|
55
47
|
ref="currentPasswordInput"
|
|
56
48
|
v-model="form.current_password"
|
|
@@ -63,9 +55,9 @@ const updatePassword = () => {
|
|
|
63
55
|
</div>
|
|
64
56
|
|
|
65
57
|
<div>
|
|
66
|
-
<
|
|
58
|
+
<Label for="password">New Password</Label>
|
|
67
59
|
|
|
68
|
-
<
|
|
60
|
+
<Input
|
|
69
61
|
id="password"
|
|
70
62
|
ref="passwordInput"
|
|
71
63
|
v-model="form.password"
|
|
@@ -78,9 +70,9 @@ const updatePassword = () => {
|
|
|
78
70
|
</div>
|
|
79
71
|
|
|
80
72
|
<div>
|
|
81
|
-
<
|
|
73
|
+
<Label for="password_confirmation">Confirm Password</Label>
|
|
82
74
|
|
|
83
|
-
<
|
|
75
|
+
<Input
|
|
84
76
|
id="password_confirmation"
|
|
85
77
|
v-model="form.password_confirmation"
|
|
86
78
|
type="password"
|
|
@@ -92,7 +84,7 @@ const updatePassword = () => {
|
|
|
92
84
|
</div>
|
|
93
85
|
|
|
94
86
|
<div class="flex items-center gap-4">
|
|
95
|
-
<
|
|
87
|
+
<Button :disabled="form.processing">Save</Button>
|
|
96
88
|
|
|
97
89
|
<Transition
|
|
98
90
|
enter-active-class="transition ease-in-out"
|
|
@@ -100,7 +92,7 @@ const updatePassword = () => {
|
|
|
100
92
|
leave-active-class="transition ease-in-out"
|
|
101
93
|
leave-to-class="opacity-0"
|
|
102
94
|
>
|
|
103
|
-
<p v-if="form.recentlySuccessful" class="text-sm text-
|
|
95
|
+
<p v-if="form.recentlySuccessful" class="text-sm text-muted-foreground">Saved.</p>
|
|
104
96
|
</Transition>
|
|
105
97
|
</div>
|
|
106
98
|
</form>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import InputError from '@/Components/InputError.vue'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
3
|
+
import { Button } from '@/Components/ui/button'
|
|
4
|
+
import { Input } from '@/Components/ui/input'
|
|
5
|
+
import { Label } from '@/Components/ui/label'
|
|
6
6
|
import { Link, useForm, usePage } from '@inertiajs/vue3'
|
|
7
7
|
import { profile_update_path, verification_send_path } from '@/routes'
|
|
8
8
|
|
|
@@ -21,19 +21,11 @@ const form = useForm({
|
|
|
21
21
|
|
|
22
22
|
<template>
|
|
23
23
|
<section>
|
|
24
|
-
<
|
|
25
|
-
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">Profile Information</h2>
|
|
26
|
-
|
|
27
|
-
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
|
|
28
|
-
Update your account's profile information and email address.
|
|
29
|
-
</p>
|
|
30
|
-
</header>
|
|
31
|
-
|
|
32
|
-
<form @submit.prevent="form.patch(profile_update_path())" class="mt-6 space-y-6">
|
|
24
|
+
<form @submit.prevent="form.patch(profile_update_path())" class="space-y-6">
|
|
33
25
|
<div>
|
|
34
|
-
<
|
|
26
|
+
<Label for="name">Name</Label>
|
|
35
27
|
|
|
36
|
-
<
|
|
28
|
+
<Input
|
|
37
29
|
id="name"
|
|
38
30
|
type="text"
|
|
39
31
|
class="mt-1 block w-full"
|
|
@@ -47,9 +39,9 @@ const form = useForm({
|
|
|
47
39
|
</div>
|
|
48
40
|
|
|
49
41
|
<div>
|
|
50
|
-
<
|
|
42
|
+
<Label for="email">Email</Label>
|
|
51
43
|
|
|
52
|
-
<
|
|
44
|
+
<Input
|
|
53
45
|
id="email"
|
|
54
46
|
type="email"
|
|
55
47
|
class="mt-1 block w-full"
|
|
@@ -62,13 +54,13 @@ const form = useForm({
|
|
|
62
54
|
</div>
|
|
63
55
|
|
|
64
56
|
<div v-if="mustVerifyEmail && user.email_verified_at === null">
|
|
65
|
-
<p class="
|
|
57
|
+
<p class="mt-2 text-sm text-foreground">
|
|
66
58
|
Your email address is unverified.
|
|
67
59
|
<Link
|
|
68
60
|
:href="verification_send_path()"
|
|
69
61
|
method="post"
|
|
70
62
|
as="button"
|
|
71
|
-
class="
|
|
63
|
+
class="rounded-md text-sm text-muted-foreground underline outline-none hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
|
72
64
|
>
|
|
73
65
|
Click here to re-send the verification email.
|
|
74
66
|
</Link>
|
|
@@ -83,7 +75,7 @@ const form = useForm({
|
|
|
83
75
|
</div>
|
|
84
76
|
|
|
85
77
|
<div class="flex items-center gap-4">
|
|
86
|
-
<
|
|
78
|
+
<Button :disabled="form.processing">Save</Button>
|
|
87
79
|
|
|
88
80
|
<Transition
|
|
89
81
|
enter-active-class="transition ease-in-out"
|
|
@@ -91,7 +83,7 @@ const form = useForm({
|
|
|
91
83
|
leave-active-class="transition ease-in-out"
|
|
92
84
|
leave-to-class="opacity-0"
|
|
93
85
|
>
|
|
94
|
-
<p v-if="form.recentlySuccessful" class="text-sm text-
|
|
86
|
+
<p v-if="form.recentlySuccessful" class="text-sm text-muted-foreground">Saved.</p>
|
|
95
87
|
</Transition>
|
|
96
88
|
</div>
|
|
97
89
|
</form>
|
|
@@ -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 UpdatePasswordForm from './Partials/UpdatePasswordForm.vue'
|
|
7
|
+
import { password_edit_path } from '@/routes'
|
|
8
|
+
import { BreadcrumbItem } from '@/types'
|
|
9
|
+
|
|
10
|
+
const breadcrumbs: BreadcrumbItem[] = [
|
|
11
|
+
{
|
|
12
|
+
title: 'Password settings',
|
|
13
|
+
href: password_edit_path(),
|
|
14
|
+
},
|
|
15
|
+
]
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<Head title="Password settings" />
|
|
20
|
+
|
|
21
|
+
<AuthenticatedLayout :breadcrumbs="breadcrumbs">
|
|
22
|
+
<SettingsLayout>
|
|
23
|
+
<div class="space-y-6">
|
|
24
|
+
<Heading
|
|
25
|
+
variant="small"
|
|
26
|
+
title="Update password"
|
|
27
|
+
description="Ensure your account is using a long, random password to stay secure"
|
|
28
|
+
/>
|
|
29
|
+
<UpdatePasswordForm />
|
|
30
|
+
</div>
|
|
31
|
+
</SettingsLayout>
|
|
32
|
+
</AuthenticatedLayout>
|
|
33
|
+
</template>
|
|
@@ -0,0 +1,40 @@
|
|
|
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 DeleteUserForm from './Partials/DeleteUserForm.vue'
|
|
7
|
+
import UpdateProfileInformationForm from './Partials/UpdateProfileInformationForm.vue'
|
|
8
|
+
import { profile_edit_path } from '@/routes'
|
|
9
|
+
import { BreadcrumbItem } from '@/types'
|
|
10
|
+
|
|
11
|
+
defineProps<{
|
|
12
|
+
mustVerifyEmail?: boolean
|
|
13
|
+
status?: string
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const breadcrumbs: BreadcrumbItem[] = [
|
|
17
|
+
{
|
|
18
|
+
title: 'Profile settings',
|
|
19
|
+
href: profile_edit_path(),
|
|
20
|
+
},
|
|
21
|
+
]
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<Head title="Profile settings" />
|
|
26
|
+
|
|
27
|
+
<AuthenticatedLayout :breadcrumbs="breadcrumbs">
|
|
28
|
+
<SettingsLayout>
|
|
29
|
+
<div class="space-y-6">
|
|
30
|
+
<Heading variant="small" title="Profile information" description="Update your name and email address" />
|
|
31
|
+
<UpdateProfileInformationForm :must-verify-email="mustVerifyEmail" :status="status" />
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class="space-y-6">
|
|
35
|
+
<Heading variant="small" title="Delete account" description="Delete your account and all of its resources" />
|
|
36
|
+
<DeleteUserForm />
|
|
37
|
+
</div>
|
|
38
|
+
</SettingsLayout>
|
|
39
|
+
</AuthenticatedLayout>
|
|
40
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type UseInitialsReturn = {
|
|
2
|
+
getInitials: (fullName?: string) => string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function getInitial(name: string): string {
|
|
6
|
+
return Array.from(name)[0] ?? ''
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getInitials(fullName?: string): string {
|
|
10
|
+
if (!fullName) {
|
|
11
|
+
return ''
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const names = fullName.trim().split(/\s+/u).filter(Boolean)
|
|
15
|
+
|
|
16
|
+
if (names.length === 0) {
|
|
17
|
+
return ''
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (names.length === 1) {
|
|
21
|
+
return getInitial(names[0]).toUpperCase()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return `${getInitial(names[0])}${getInitial(names[names.length - 1])}`.toUpperCase()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useInitials(): UseInitialsReturn {
|
|
28
|
+
return { getInitials }
|
|
29
|
+
}
|
|
@@ -10,8 +10,7 @@ export function getAppearance(): Appearance {
|
|
|
10
10
|
|
|
11
11
|
export function applyAppearance(appearance: Appearance = getAppearance()): void {
|
|
12
12
|
const dark =
|
|
13
|
-
appearance === 'dark' ||
|
|
14
|
-
(appearance === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
13
|
+
appearance === 'dark' || (appearance === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
15
14
|
|
|
16
15
|
document.documentElement.classList.toggle('dark', dark)
|
|
17
16
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Component } from 'vue'
|
|
2
|
+
|
|
1
3
|
export interface User {
|
|
2
4
|
id: number
|
|
3
5
|
name: string
|
|
@@ -5,8 +7,20 @@ export interface User {
|
|
|
5
7
|
email_verified_at?: string
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
export interface NavItem {
|
|
11
|
+
title: string
|
|
12
|
+
href: string
|
|
13
|
+
icon?: Component
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface BreadcrumbItem {
|
|
17
|
+
title: string
|
|
18
|
+
href: string
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
export type PageProps<T extends Record<string, unknown> = Record<string, unknown>> = T & {
|
|
9
22
|
auth: {
|
|
10
23
|
user: User
|
|
11
24
|
}
|
|
25
|
+
sidebar_open: boolean
|
|
12
26
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Lets plain `tsc` resolve single-file components imported from .ts modules,
|
|
2
|
+
// such as the `index.ts` barrels the ui components use. vue-tsc would give
|
|
3
|
+
// richer types, but it does not currently run against TypeScript 7.
|
|
4
|
+
declare module '*.vue' {
|
|
5
|
+
import type { DefineComponent } from 'vue'
|
|
6
|
+
|
|
7
|
+
const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>
|
|
8
|
+
|
|
9
|
+
export default component
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://shadcn-vue.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"typescript": true,
|
|
5
|
+
"tailwind": {
|
|
6
|
+
"config": "",
|
|
7
|
+
"css": "app/assets/tailwind/application.css",
|
|
8
|
+
"baseColor": "neutral",
|
|
9
|
+
"cssVariables": true,
|
|
10
|
+
"prefix": ""
|
|
11
|
+
},
|
|
12
|
+
"aliases": {
|
|
13
|
+
"components": "@/Components",
|
|
14
|
+
"ui": "@/Components/ui",
|
|
15
|
+
"utils": "@/lib/utils",
|
|
16
|
+
"lib": "@/lib",
|
|
17
|
+
"composables": "@/composables"
|
|
18
|
+
},
|
|
19
|
+
"iconLibrary": "lucide"
|
|
20
|
+
}
|
|
@@ -8,10 +8,17 @@
|
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@headlessui/vue": "^1.7.23",
|
|
10
10
|
"@inertiajs/vue3": "^3.9.1",
|
|
11
|
+
"@lucide/vue": "^1.61.0",
|
|
11
12
|
"@types/node": "^26.6.5",
|
|
12
13
|
"@vitejs/plugin-vue": "^6.0.10",
|
|
14
|
+
"@vueuse/core": "^12.8.2",
|
|
13
15
|
"axios": "^1.6.4",
|
|
14
|
-
"
|
|
16
|
+
"class-variance-authority": "^0.7.1",
|
|
17
|
+
"clsx": "^2.1.1",
|
|
18
|
+
"reka-ui": "^2.11.0",
|
|
19
|
+
"tailwind-merge": "^3.7.0",
|
|
20
|
+
"tw-animate-css": "^1.4.0",
|
|
21
|
+
"typescript": "^5.9.3",
|
|
15
22
|
"vite": "^8.3.4",
|
|
16
23
|
"vite-plugin-rails": "^0.6.0",
|
|
17
24
|
"vue": "^3.5.44",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
1
2
|
import { defineConfig } from 'vite'
|
|
2
3
|
import Rails from 'vite-plugin-rails'
|
|
3
4
|
import vue from '@vitejs/plugin-vue'
|
|
@@ -6,5 +7,28 @@ export default defineConfig({
|
|
|
6
7
|
resolve: {
|
|
7
8
|
dedupe: ['axios'],
|
|
8
9
|
},
|
|
9
|
-
plugins: [
|
|
10
|
+
plugins: [
|
|
11
|
+
Rails(),
|
|
12
|
+
vue({
|
|
13
|
+
script: {
|
|
14
|
+
// Components that type their props from another package -- the ui
|
|
15
|
+
// primitives do this with reka-ui -- need the SFC compiler to read
|
|
16
|
+
// files to resolve those types. It does not assume filesystem access,
|
|
17
|
+
// so hand it one.
|
|
18
|
+
fs: {
|
|
19
|
+
// statSync, not existsSync: a barrel import like `from "."` probes the
|
|
20
|
+
// directory itself, and claiming it exists makes the compiler try to
|
|
21
|
+
// read a directory.
|
|
22
|
+
fileExists: (file: string) => {
|
|
23
|
+
try {
|
|
24
|
+
return fs.statSync(file).isFile()
|
|
25
|
+
} catch {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
readFile: (file: string) => fs.readFileSync(file, 'utf-8'),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
10
34
|
})
|