kaze 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +42 -0
  4. data/bin/kaze +11 -0
  5. data/lib/kaze/commands/install_command.rb +63 -0
  6. data/lib/kaze/commands/install_inertia_stacks.rb +151 -0
  7. data/lib/kaze/commands.rb +2 -0
  8. data/lib/kaze/version.rb +3 -0
  9. data/lib/kaze.rb +9 -0
  10. data/stubs/default/Procfile.dev +3 -0
  11. data/stubs/default/app/assets/stylesheets/application.css +1 -0
  12. data/stubs/default/app/assets/stylesheets/application.tailwind.css +3 -0
  13. data/stubs/default/app/controllers/application_controller.rb +5 -0
  14. data/stubs/default/app/controllers/auth/authenticated_session_controller.rb +28 -0
  15. data/stubs/default/app/controllers/auth/new_password_controller.rb +18 -0
  16. data/stubs/default/app/controllers/auth/password_reset_link_controller.rb +17 -0
  17. data/stubs/default/app/controllers/auth/registered_user_controller.rb +19 -0
  18. data/stubs/default/app/controllers/concerns/authenticate.rb +34 -0
  19. data/stubs/default/app/controllers/concerns/handle_inertia_requests.rb +9 -0
  20. data/stubs/default/app/controllers/concerns/verify_csrf_token.rb +24 -0
  21. data/stubs/default/app/controllers/dashboard_controller.rb +5 -0
  22. data/stubs/default/app/controllers/password_controller.rb +11 -0
  23. data/stubs/default/app/controllers/profile_controller.rb +31 -0
  24. data/stubs/default/app/controllers/welcome_controller.rb +10 -0
  25. data/stubs/default/app/forms/application_form.rb +9 -0
  26. data/stubs/default/app/forms/auth/login_form.rb +18 -0
  27. data/stubs/default/app/forms/auth/new_password_form.rb +21 -0
  28. data/stubs/default/app/forms/auth/register_form.rb +7 -0
  29. data/stubs/default/app/forms/auth/send_password_reset_link_form.rb +22 -0
  30. data/stubs/default/app/forms/delete_user_form.rb +5 -0
  31. data/stubs/default/app/forms/update_password_form.rb +6 -0
  32. data/stubs/default/app/forms/update_profile_information_form.rb +6 -0
  33. data/stubs/default/app/mailers/application_mailer.rb +11 -0
  34. data/stubs/default/app/mailers/user_mailer.rb +8 -0
  35. data/stubs/default/app/models/application_record.rb +3 -0
  36. data/stubs/default/app/models/concerns/can_reset_password.rb +5 -0
  37. data/stubs/default/app/models/current.rb +3 -0
  38. data/stubs/default/app/models/user.rb +11 -0
  39. data/stubs/default/app/validators/current_password_validator.rb +5 -0
  40. data/stubs/default/app/validators/email_validator.rb +7 -0
  41. data/stubs/default/app/validators/lowercase_validator.rb +5 -0
  42. data/stubs/default/app/validators/uniqueness_validator.rb +24 -0
  43. data/stubs/default/app/views/layouts/mailer.html.erb +374 -0
  44. data/stubs/default/app/views/layouts/mailer.text.erb +11 -0
  45. data/stubs/default/app/views/user_mailer/reset_password.html.erb +39 -0
  46. data/stubs/default/bin/dev +16 -0
  47. data/stubs/default/bin/vite +27 -0
  48. data/stubs/default/config/routes.rb +27 -0
  49. data/stubs/default/config/vite.json +16 -0
  50. data/stubs/default/db/migrate/20240101000000_create_users.rb +14 -0
  51. data/stubs/default/db/migrate/20240101000001_create_delayed_jobs.rb +22 -0
  52. data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +12 -0
  53. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +14 -0
  54. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +17 -0
  55. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +99 -0
  56. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +9 -0
  57. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +9 -0
  58. data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +68 -0
  59. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +18 -0
  60. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +17 -0
  61. data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +16 -0
  62. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +18 -0
  63. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +30 -0
  64. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +131 -0
  65. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +19 -0
  66. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -0
  67. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +98 -0
  68. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -0
  69. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +74 -0
  70. data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +22 -0
  71. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +33 -0
  72. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +100 -0
  73. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +114 -0
  74. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +84 -0
  75. data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +66 -0
  76. data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +34 -0
  77. data/stubs/inertia-react-ts/app/javascript/entrypoints/bootstrap.ts +4 -0
  78. data/stubs/inertia-react-ts/app/javascript/types/global.d.ts +7 -0
  79. data/stubs/inertia-react-ts/app/javascript/types/index.d.ts +12 -0
  80. data/stubs/inertia-react-ts/app/javascript/types/vite-env.d.ts +1 -0
  81. data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +26 -0
  82. data/stubs/inertia-react-ts/config/tailwind.config.js +22 -0
  83. data/stubs/inertia-react-ts/package.json +26 -0
  84. data/stubs/inertia-react-ts/tsconfig.json +19 -0
  85. data/stubs/inertia-react-ts/vite.config.ts +13 -0
  86. data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +8 -0
  87. data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +29 -0
  88. data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +7 -0
  89. data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +75 -0
  90. data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +16 -0
  91. data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +13 -0
  92. data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +12 -0
  93. data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +96 -0
  94. data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +21 -0
  95. data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +7 -0
  96. data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +21 -0
  97. data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +19 -0
  98. data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +23 -0
  99. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +155 -0
  100. data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +20 -0
  101. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +60 -0
  102. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +93 -0
  103. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +106 -0
  104. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +89 -0
  105. data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -0
  106. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +42 -0
  107. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +98 -0
  108. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +108 -0
  109. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +78 -0
  110. data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +56 -0
  111. data/stubs/inertia-vue-ts/app/javascript/entrypoints/application.ts +34 -0
  112. data/stubs/inertia-vue-ts/app/javascript/entrypoints/bootstrap.ts +4 -0
  113. data/stubs/inertia-vue-ts/app/javascript/types/global.d.ts +13 -0
  114. data/stubs/inertia-vue-ts/app/javascript/types/index.d.ts +12 -0
  115. data/stubs/inertia-vue-ts/app/javascript/types/vite-env.d.ts +1 -0
  116. data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +25 -0
  117. data/stubs/inertia-vue-ts/config/tailwind.config.js +22 -0
  118. data/stubs/inertia-vue-ts/package.json +24 -0
  119. data/stubs/inertia-vue-ts/tsconfig.json +19 -0
  120. data/stubs/inertia-vue-ts/vite.config.ts +13 -0
  121. metadata +205 -0
@@ -0,0 +1,155 @@
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 : {};
14
+ </script>
15
+
16
+ <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="dashboard_path()">
27
+ <ApplicationLogo
28
+ class="block h-9 w-auto fill-current text-gray-800 dark:text-gray-200"
29
+ />
30
+ </Link>
31
+ </div>
32
+
33
+ <!-- Navigation Links -->
34
+ <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
35
+ <NavLink :href="dashboard_path()" :active="pathname.match(/dashboard/) != null">
36
+ Dashboard
37
+ </NavLink>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="hidden sm:flex sm:items-center sm:ms-6">
42
+ <!-- Settings Dropdown -->
43
+ <div class="ms-3 relative">
44
+ <Dropdown align="right" width="48">
45
+ <template #trigger>
46
+ <span class="inline-flex rounded-md">
47
+ <button
48
+ type="button"
49
+ 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-none transition ease-in-out duration-150"
50
+ >
51
+ {{ $page.props.auth.user.name }}
52
+
53
+ <svg
54
+ class="ms-2 -me-0.5 h-4 w-4"
55
+ xmlns="http://www.w3.org/2000/svg"
56
+ viewBox="0 0 20 20"
57
+ fill="currentColor"
58
+ >
59
+ <path
60
+ fill-rule="evenodd"
61
+ 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"
62
+ clip-rule="evenodd"
63
+ />
64
+ </svg>
65
+ </button>
66
+ </span>
67
+ </template>
68
+
69
+ <template #content>
70
+ <DropdownLink :href="profile_edit_path()"> Profile </DropdownLink>
71
+ <DropdownLink :href="logout_path()" method="post" as="button">
72
+ Log Out
73
+ </DropdownLink>
74
+ </template>
75
+ </Dropdown>
76
+ </div>
77
+ </div>
78
+
79
+ <!-- Hamburger -->
80
+ <div class="-me-2 flex items-center sm:hidden">
81
+ <button
82
+ @click="showingNavigationDropdown = !showingNavigationDropdown"
83
+ 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-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-500 dark:focus:text-gray-400 transition duration-150 ease-in-out"
84
+ >
85
+ <svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
86
+ <path
87
+ :class="{
88
+ hidden: showingNavigationDropdown,
89
+ 'inline-flex': !showingNavigationDropdown,
90
+ }"
91
+ stroke-linecap="round"
92
+ stroke-linejoin="round"
93
+ stroke-width="2"
94
+ d="M4 6h16M4 12h16M4 18h16"
95
+ />
96
+ <path
97
+ :class="{
98
+ hidden: !showingNavigationDropdown,
99
+ 'inline-flex': showingNavigationDropdown,
100
+ }"
101
+ stroke-linecap="round"
102
+ stroke-linejoin="round"
103
+ stroke-width="2"
104
+ d="M6 18L18 6M6 6l12 12"
105
+ />
106
+ </svg>
107
+ </button>
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- Responsive Navigation Menu -->
113
+ <div
114
+ :class="{ block: showingNavigationDropdown, hidden: !showingNavigationDropdown }"
115
+ class="sm:hidden"
116
+ >
117
+ <div class="pt-2 pb-3 space-y-1">
118
+ <ResponsiveNavLink :href="dashboard_path()" :active="pathname.match(/dashboard/) != null">
119
+ Dashboard
120
+ </ResponsiveNavLink>
121
+ </div>
122
+
123
+ <!-- Responsive Settings Options -->
124
+ <div class="pt-4 pb-1 border-t border-gray-200 dark:border-gray-600">
125
+ <div class="px-4">
126
+ <div class="font-medium text-base text-gray-800 dark:text-gray-200">
127
+ {{ $page.props.auth.user.name }}
128
+ </div>
129
+ <div class="font-medium text-sm text-gray-500">{{ $page.props.auth.user.email }}</div>
130
+ </div>
131
+
132
+ <div class="mt-3 space-y-1">
133
+ <ResponsiveNavLink :href="profile_edit_path()"> Profile </ResponsiveNavLink>
134
+ <ResponsiveNavLink :href="logout_path()" method="post" as="button">
135
+ Log Out
136
+ </ResponsiveNavLink>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </nav>
141
+
142
+ <!-- Page Heading -->
143
+ <header class="bg-white dark:bg-gray-800 shadow" v-if="$slots.header">
144
+ <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
145
+ <slot name="header" />
146
+ </div>
147
+ </header>
148
+
149
+ <!-- Page Content -->
150
+ <main>
151
+ <slot />
152
+ </main>
153
+ </div>
154
+ </div>
155
+ </template>
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ import ApplicationLogo from '@/Components/ApplicationLogo.vue';
3
+ import { Link } from '@inertiajs/vue3';
4
+ </script>
5
+
6
+ <template>
7
+ <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100 dark:bg-gray-900">
8
+ <div>
9
+ <Link href="/">
10
+ <ApplicationLogo class="w-20 h-20 fill-current text-gray-500" />
11
+ </Link>
12
+ </div>
13
+
14
+ <div
15
+ class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg"
16
+ >
17
+ <slot />
18
+ </div>
19
+ </div>
20
+ </template>
@@ -0,0 +1,60 @@
1
+ <script setup lang="ts">
2
+ import GuestLayout from '@/Layouts/GuestLayout.vue';
3
+ 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
+ import { Head, useForm } from '@inertiajs/vue3';
8
+ import { password_email_path } from '@/routes';
9
+
10
+ defineProps<{
11
+ status?: string;
12
+ }>();
13
+
14
+ const form = useForm({
15
+ email: '',
16
+ });
17
+
18
+ const submit = () => {
19
+ form.post(password_email_path());
20
+ };
21
+ </script>
22
+
23
+ <template>
24
+ <GuestLayout>
25
+ <Head title="Forgot Password" />
26
+
27
+ <div class="mb-4 text-sm text-gray-600 dark:text-gray-400">
28
+ Forgot your password? No problem. Just let us know your email address and we will email you a password reset
29
+ link that will allow you to choose a new one.
30
+ </div>
31
+
32
+ <div v-if="status" class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
33
+ {{ status }}
34
+ </div>
35
+
36
+ <form @submit.prevent="submit">
37
+ <div>
38
+ <InputLabel for="email" value="Email" />
39
+
40
+ <TextInput
41
+ id="email"
42
+ type="email"
43
+ class="mt-1 block w-full"
44
+ v-model="form.email"
45
+ required
46
+ autofocus
47
+ autocomplete="username"
48
+ />
49
+
50
+ <InputError class="mt-2" :message="form.errors.email" />
51
+ </div>
52
+
53
+ <div class="flex items-center justify-end mt-4">
54
+ <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
55
+ Email Password Reset Link
56
+ </PrimaryButton>
57
+ </div>
58
+ </form>
59
+ </GuestLayout>
60
+ </template>
@@ -0,0 +1,93 @@
1
+ <script setup lang="ts">
2
+ import Checkbox from '@/Components/Checkbox.vue';
3
+ import GuestLayout from '@/Layouts/GuestLayout.vue';
4
+ 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
+ import { Head, Link, useForm } from '@inertiajs/vue3';
9
+ import { login_path, password_request_path } from '@/routes';
10
+
11
+ defineProps<{
12
+ canResetPassword?: boolean;
13
+ status?: string;
14
+ }>();
15
+
16
+ const form = useForm({
17
+ email: '',
18
+ password: '',
19
+ remember: false,
20
+ });
21
+
22
+ const submit = () => {
23
+ form.post(login_path(), {
24
+ onFinish: () => {
25
+ form.reset('password');
26
+ },
27
+ });
28
+ };
29
+ </script>
30
+
31
+ <template>
32
+ <GuestLayout>
33
+ <Head title="Log in" />
34
+
35
+ <div v-if="status" class="mb-4 font-medium text-sm text-green-600">
36
+ {{ status }}
37
+ </div>
38
+
39
+ <form @submit.prevent="submit">
40
+ <div>
41
+ <InputLabel for="email" value="Email" />
42
+
43
+ <TextInput
44
+ id="email"
45
+ type="email"
46
+ class="mt-1 block w-full"
47
+ v-model="form.email"
48
+ required
49
+ autofocus
50
+ autocomplete="username"
51
+ />
52
+
53
+ <InputError class="mt-2" :message="form.errors.email" />
54
+ </div>
55
+
56
+ <div class="mt-4">
57
+ <InputLabel for="password" value="Password" />
58
+
59
+ <TextInput
60
+ id="password"
61
+ type="password"
62
+ class="mt-1 block w-full"
63
+ v-model="form.password"
64
+ required
65
+ autocomplete="current-password"
66
+ />
67
+
68
+ <InputError class="mt-2" :message="form.errors.password" />
69
+ </div>
70
+
71
+ <div class="block mt-4">
72
+ <label class="flex items-center">
73
+ <Checkbox name="remember" v-model:checked="form.remember" />
74
+ <span class="ms-2 text-sm text-gray-600 dark:text-gray-400">Remember me</span>
75
+ </label>
76
+ </div>
77
+
78
+ <div class="flex items-center justify-end mt-4">
79
+ <Link
80
+ v-if="canResetPassword"
81
+ :href="password_request_path()"
82
+ class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800"
83
+ >
84
+ Forgot your password?
85
+ </Link>
86
+
87
+ <PrimaryButton class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
88
+ Log in
89
+ </PrimaryButton>
90
+ </div>
91
+ </form>
92
+ </GuestLayout>
93
+ </template>
@@ -0,0 +1,106 @@
1
+ <script setup lang="ts">
2
+ import GuestLayout from '@/Layouts/GuestLayout.vue';
3
+ 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
+ import { Head, Link, useForm } from '@inertiajs/vue3';
8
+ import { login_path, register_path } from '@/routes';
9
+
10
+ const form = useForm({
11
+ name: '',
12
+ email: '',
13
+ password: '',
14
+ password_confirmation: '',
15
+ });
16
+
17
+ const submit = () => {
18
+ form.post(register_path(), {
19
+ onFinish: () => {
20
+ form.reset('password', 'password_confirmation');
21
+ },
22
+ });
23
+ };
24
+ </script>
25
+
26
+ <template>
27
+ <GuestLayout>
28
+ <Head title="Register" />
29
+
30
+ <form @submit.prevent="submit">
31
+ <div>
32
+ <InputLabel for="name" value="Name" />
33
+
34
+ <TextInput
35
+ id="name"
36
+ type="text"
37
+ class="mt-1 block w-full"
38
+ v-model="form.name"
39
+ required
40
+ autofocus
41
+ autocomplete="name"
42
+ />
43
+
44
+ <InputError class="mt-2" :message="form.errors.name" />
45
+ </div>
46
+
47
+ <div class="mt-4">
48
+ <InputLabel for="email" value="Email" />
49
+
50
+ <TextInput
51
+ id="email"
52
+ type="email"
53
+ class="mt-1 block w-full"
54
+ v-model="form.email"
55
+ required
56
+ autocomplete="username"
57
+ />
58
+
59
+ <InputError class="mt-2" :message="form.errors.email" />
60
+ </div>
61
+
62
+ <div class="mt-4">
63
+ <InputLabel for="password" value="Password" />
64
+
65
+ <TextInput
66
+ id="password"
67
+ type="password"
68
+ class="mt-1 block w-full"
69
+ v-model="form.password"
70
+ required
71
+ autocomplete="new-password"
72
+ />
73
+
74
+ <InputError class="mt-2" :message="form.errors.password" />
75
+ </div>
76
+
77
+ <div class="mt-4">
78
+ <InputLabel for="password_confirmation" value="Confirm Password" />
79
+
80
+ <TextInput
81
+ id="password_confirmation"
82
+ type="password"
83
+ class="mt-1 block w-full"
84
+ v-model="form.password_confirmation"
85
+ required
86
+ autocomplete="new-password"
87
+ />
88
+
89
+ <InputError class="mt-2" :message="form.errors.password_confirmation" />
90
+ </div>
91
+
92
+ <div class="flex items-center justify-end mt-4">
93
+ <Link
94
+ :href="login_path()"
95
+ class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800"
96
+ >
97
+ Already registered?
98
+ </Link>
99
+
100
+ <PrimaryButton class="ms-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
101
+ Register
102
+ </PrimaryButton>
103
+ </div>
104
+ </form>
105
+ </GuestLayout>
106
+ </template>
@@ -0,0 +1,89 @@
1
+ <script setup lang="ts">
2
+ import GuestLayout from '@/Layouts/GuestLayout.vue';
3
+ 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
+ import { Head, useForm } from '@inertiajs/vue3';
8
+ import { password_store_path } from '@/routes';
9
+
10
+ const props = defineProps<{
11
+ email: string;
12
+ token: string;
13
+ }>();
14
+
15
+ const form = useForm({
16
+ token: props.token,
17
+ email: props.email,
18
+ password: '',
19
+ password_confirmation: '',
20
+ });
21
+
22
+ const submit = () => {
23
+ form.post(password_store_path(), {
24
+ onFinish: () => {
25
+ form.reset('password', 'password_confirmation');
26
+ },
27
+ });
28
+ };
29
+ </script>
30
+
31
+ <template>
32
+ <GuestLayout>
33
+ <Head title="Reset Password" />
34
+
35
+ <form @submit.prevent="submit">
36
+ <div>
37
+ <InputLabel for="email" value="Email" />
38
+
39
+ <TextInput
40
+ id="email"
41
+ type="email"
42
+ class="mt-1 block w-full"
43
+ v-model="form.email"
44
+ required
45
+ autofocus
46
+ autocomplete="username"
47
+ />
48
+
49
+ <InputError class="mt-2" :message="form.errors.email" />
50
+ </div>
51
+
52
+ <div class="mt-4">
53
+ <InputLabel for="password" value="Password" />
54
+
55
+ <TextInput
56
+ id="password"
57
+ type="password"
58
+ class="mt-1 block w-full"
59
+ v-model="form.password"
60
+ required
61
+ autocomplete="new-password"
62
+ />
63
+
64
+ <InputError class="mt-2" :message="form.errors.password" />
65
+ </div>
66
+
67
+ <div class="mt-4">
68
+ <InputLabel for="password_confirmation" value="Confirm Password" />
69
+
70
+ <TextInput
71
+ id="password_confirmation"
72
+ type="password"
73
+ class="mt-1 block w-full"
74
+ v-model="form.password_confirmation"
75
+ required
76
+ autocomplete="new-password"
77
+ />
78
+
79
+ <InputError class="mt-2" :message="form.errors.password_confirmation" />
80
+ </div>
81
+
82
+ <div class="flex items-center justify-end mt-4">
83
+ <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
84
+ Reset Password
85
+ </PrimaryButton>
86
+ </div>
87
+ </form>
88
+ </GuestLayout>
89
+ </template>
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
3
+ import { Head } from '@inertiajs/vue3';
4
+ </script>
5
+
6
+ <template>
7
+ <Head title="Dashboard" />
8
+
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-sm sm:rounded-lg">
17
+ <div class="p-6 text-gray-900 dark:text-gray-100">You're logged in!</div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </AuthenticatedLayout>
22
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
3
+ import DeleteUserForm from './Partials/DeleteUserForm.vue';
4
+ import UpdatePasswordForm from './Partials/UpdatePasswordForm.vue';
5
+ import UpdateProfileInformationForm from './Partials/UpdateProfileInformationForm.vue';
6
+ import { Head } from '@inertiajs/vue3';
7
+
8
+ defineProps<{
9
+ mustVerifyEmail?: boolean;
10
+ status?: string;
11
+ }>();
12
+ </script>
13
+
14
+ <template>
15
+ <Head title="Profile" />
16
+
17
+ <AuthenticatedLayout>
18
+ <template #header>
19
+ <h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">Profile</h2>
20
+ </template>
21
+
22
+ <div class="py-12">
23
+ <div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
24
+ <div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
25
+ <UpdateProfileInformationForm
26
+ :must-verify-email="mustVerifyEmail"
27
+ :status="status"
28
+ class="max-w-xl"
29
+ />
30
+ </div>
31
+
32
+ <div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
33
+ <UpdatePasswordForm class="max-w-xl" />
34
+ </div>
35
+
36
+ <div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
37
+ <DeleteUserForm class="max-w-xl" />
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </AuthenticatedLayout>
42
+ </template>