kaze 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kaze/commands/install_command.rb +8 -0
- data/lib/kaze/commands/installs_hotwire_stack.rb +5 -2
- data/lib/kaze/commands/installs_inertia_stacks.rb +13 -3
- data/lib/kaze/version.rb +1 -1
- data/stubs/default/app/forms/auth/login_form.rb +2 -8
- data/stubs/default/app/forms/update_profile_information_form.rb +1 -1
- data/stubs/default/app/models/auth.rb +57 -0
- data/stubs/default/app/models/current.rb +1 -1
- data/stubs/default/app/validators/current_password_validator.rb +1 -1
- data/stubs/default/app/views/layouts/mailer.html.erb +367 -372
- data/stubs/default/app/views/layouts/mailer.text.erb +1 -4
- data/stubs/default/app/views/user_mailer/reset_password.html.erb +21 -26
- data/stubs/default/test/factories/users.rb +7 -0
- data/stubs/default/test/integration/auth/authentication_test.rb +43 -0
- data/stubs/default/test/integration/auth/password_reset_test.rb +41 -0
- data/stubs/default/test/integration/auth/registration_test.rb +21 -0
- data/stubs/default/test/integration/password_update_test.rb +28 -0
- data/stubs/default/test/integration/profile_test.rb +51 -0
- data/stubs/default/test/test_helper.rb +38 -0
- data/stubs/hotwire/app/components/dropdown_component.html.erb +17 -18
- data/stubs/hotwire/app/components/modal_component.html.erb +55 -59
- data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
- data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +10 -7
- data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +3 -1
- data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +3 -1
- data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +4 -2
- data/stubs/hotwire/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/hotwire/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/hotwire/app/controllers/password_controller.rb +1 -1
- data/stubs/hotwire/app/controllers/profile_controller.rb +6 -4
- data/stubs/hotwire/app/controllers/welcome_controller.rb +1 -1
- data/stubs/hotwire/app/javascript/application.js +3 -3
- data/stubs/hotwire/app/views/auth/forgot_password.html.erb +12 -17
- data/stubs/hotwire/app/views/auth/login.html.erb +0 -9
- data/stubs/hotwire/app/views/auth/register.html.erb +0 -13
- data/stubs/hotwire/app/views/auth/reset_password.html.erb +0 -7
- data/stubs/hotwire/app/views/dashboard/index.html.erb +9 -10
- data/stubs/hotwire/app/views/layouts/_navigation.html.erb +77 -87
- data/stubs/hotwire/app/views/layouts/application.html.erb +0 -9
- data/stubs/hotwire/app/views/layouts/guest.html.erb +0 -6
- data/stubs/hotwire/app/views/profile/edit.html.erb +19 -22
- data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +32 -42
- data/stubs/hotwire/app/views/profile/partials/_update_password_form.html.erb +42 -55
- data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +36 -46
- data/stubs/hotwire/app/views/welcome/index.html.erb +34 -46
- data/stubs/hotwire/config/tailwind.config.js +2 -2
- data/stubs/inertia-common/app/controllers/application_controller.rb +1 -0
- data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +10 -7
- data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +3 -1
- data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +3 -1
- data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +4 -2
- data/stubs/inertia-common/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +1 -1
- data/stubs/inertia-common/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/inertia-common/app/controllers/password_controller.rb +1 -1
- data/stubs/inertia-common/app/controllers/profile_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/welcome_controller.rb +1 -1
- data/stubs/inertia-common/test/integration/password_update_test.rb +28 -0
- data/stubs/inertia-common/test/integration/profile_test.rb +51 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +13 -9
- data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +15 -12
- data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +119 -87
- data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +14 -7
- data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +18 -7
- data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +60 -60
- data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +21 -16
- data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +19 -14
- data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +22 -16
- data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +35 -24
- data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +157 -117
- data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +15 -15
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -49
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +90 -82
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -115
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +63 -60
- data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +23 -17
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +31 -27
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +109 -99
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +121 -113
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +76 -69
- data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +87 -63
- data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +32 -25
- data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-react-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-react-ts/vite.config.ts +2 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +10 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +18 -18
- data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +60 -57
- data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +9 -9
- data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +7 -7
- data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +6 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +84 -74
- data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +168 -136
- data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +15 -13
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +56 -49
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +78 -72
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +101 -97
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +71 -68
- data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -14
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +34 -30
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +87 -83
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +105 -98
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +69 -59
- data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +74 -47
- data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-vue-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-vue-ts/vite.config.ts +2 -5
- metadata +18 -6
- data/stubs/hotwire/bin/vite +0 -27
- data/stubs/inertia-common/Procfile.dev +0 -3
- /data/stubs/{hotwire → default}/Procfile.dev +0 -0
- /data/stubs/hotwire/app/javascript/{alpinejs.js → alpinejs.stub} +0 -0
@@ -1,18 +1,24 @@
|
|
1
|
-
import { ButtonHTMLAttributes } from 'react'
|
1
|
+
import { ButtonHTMLAttributes } from 'react'
|
2
2
|
|
3
|
-
export default function SecondaryButton({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
export default function SecondaryButton({
|
4
|
+
type = 'button',
|
5
|
+
className = '',
|
6
|
+
disabled,
|
7
|
+
children,
|
8
|
+
...props
|
9
|
+
}: ButtonHTMLAttributes<HTMLButtonElement>) {
|
10
|
+
return (
|
11
|
+
<button
|
12
|
+
{...props}
|
13
|
+
type={type}
|
14
|
+
className={
|
15
|
+
`inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 disabled:opacity-25 transition ease-in-out duration-150 ${
|
16
|
+
disabled && 'opacity-25'
|
17
|
+
} ` + className
|
18
|
+
}
|
19
|
+
disabled={disabled}
|
20
|
+
>
|
21
|
+
{children}
|
22
|
+
</button>
|
23
|
+
)
|
18
24
|
}
|
@@ -1,30 +1,41 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
forwardRef,
|
3
|
+
useEffect,
|
4
|
+
useImperativeHandle,
|
5
|
+
useRef,
|
6
|
+
InputHTMLAttributes,
|
7
|
+
} from 'react'
|
2
8
|
|
3
9
|
export default forwardRef(function TextInput(
|
4
|
-
|
5
|
-
|
10
|
+
{
|
11
|
+
type = 'text',
|
12
|
+
className = '',
|
13
|
+
isFocused = false,
|
14
|
+
...props
|
15
|
+
}: InputHTMLAttributes<HTMLInputElement> & { isFocused?: boolean },
|
16
|
+
ref,
|
6
17
|
) {
|
7
|
-
|
18
|
+
const localRef = useRef<HTMLInputElement>(null)
|
8
19
|
|
9
|
-
|
10
|
-
|
11
|
-
|
20
|
+
useImperativeHandle(ref, () => ({
|
21
|
+
focus: () => localRef.current?.focus(),
|
22
|
+
}))
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
24
|
+
useEffect(() => {
|
25
|
+
if (isFocused) {
|
26
|
+
localRef.current?.focus()
|
27
|
+
}
|
28
|
+
}, [])
|
18
29
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
})
|
30
|
+
return (
|
31
|
+
<input
|
32
|
+
{...props}
|
33
|
+
type={type}
|
34
|
+
className={
|
35
|
+
'border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm ' +
|
36
|
+
className
|
37
|
+
}
|
38
|
+
ref={localRef}
|
39
|
+
/>
|
40
|
+
)
|
41
|
+
})
|
@@ -1,131 +1,171 @@
|
|
1
|
-
import { useState, PropsWithChildren, ReactNode } from 'react'
|
2
|
-
import ApplicationLogo from '@/Components/ApplicationLogo'
|
3
|
-
import Dropdown from '@/Components/Dropdown'
|
4
|
-
import NavLink from '@/Components/NavLink'
|
5
|
-
import ResponsiveNavLink from '@/Components/ResponsiveNavLink'
|
6
|
-
import { Link } from '@inertiajs/react'
|
7
|
-
import { User } from '@/types'
|
8
|
-
import { dashboard_path, logout_path, profile_edit_path } from '@/routes'
|
1
|
+
import { useState, PropsWithChildren, ReactNode } from 'react'
|
2
|
+
import ApplicationLogo from '@/Components/ApplicationLogo'
|
3
|
+
import Dropdown from '@/Components/Dropdown'
|
4
|
+
import NavLink from '@/Components/NavLink'
|
5
|
+
import ResponsiveNavLink from '@/Components/ResponsiveNavLink'
|
6
|
+
import { Link } from '@inertiajs/react'
|
7
|
+
import { User } from '@/types'
|
8
|
+
import { dashboard_path, logout_path, profile_edit_path } from '@/routes'
|
9
9
|
|
10
|
-
export default function Authenticated({
|
11
|
-
|
10
|
+
export default function Authenticated({
|
11
|
+
user,
|
12
|
+
header,
|
13
|
+
children,
|
14
|
+
}: PropsWithChildren<{ user: User; header?: ReactNode }>) {
|
15
|
+
const [showingNavigationDropdown, setShowingNavigationDropdown] =
|
16
|
+
useState(false)
|
12
17
|
|
13
|
-
|
18
|
+
const { pathname = '' } = typeof window !== 'undefined' ? window.location : {}
|
14
19
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
return (
|
21
|
+
<div className="min-h-screen bg-gray-100">
|
22
|
+
<nav className="bg-white border-b border-gray-100">
|
23
|
+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
24
|
+
<div className="flex justify-between h-16">
|
25
|
+
<div className="flex">
|
26
|
+
<div className="shrink-0 flex items-center">
|
27
|
+
<Link href="/">
|
28
|
+
<ApplicationLogo className="block h-9 w-auto fill-current text-gray-800" />
|
29
|
+
</Link>
|
30
|
+
</div>
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
<div className="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
|
33
|
+
<NavLink
|
34
|
+
href={dashboard_path()}
|
35
|
+
active={pathname.match(/dashboard/) != null}
|
36
|
+
>
|
37
|
+
Dashboard
|
38
|
+
</NavLink>
|
39
|
+
</div>
|
40
|
+
</div>
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
<div className="hidden sm:flex sm:items-center sm:ms-6">
|
43
|
+
<div className="ms-3 relative">
|
44
|
+
<Dropdown>
|
45
|
+
<Dropdown.Trigger>
|
46
|
+
<span className="inline-flex rounded-md">
|
47
|
+
<button
|
48
|
+
type="button"
|
49
|
+
className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none transition ease-in-out duration-150"
|
50
|
+
>
|
51
|
+
{user.name}
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
<svg
|
54
|
+
className="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
|
+
fillRule="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
|
+
clipRule="evenodd"
|
63
|
+
/>
|
64
|
+
</svg>
|
65
|
+
</button>
|
66
|
+
</span>
|
67
|
+
</Dropdown.Trigger>
|
60
68
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
<Dropdown.Content>
|
70
|
+
<Dropdown.Link href={profile_edit_path()}>
|
71
|
+
Profile
|
72
|
+
</Dropdown.Link>
|
73
|
+
<Dropdown.Link
|
74
|
+
href={logout_path()}
|
75
|
+
method="post"
|
76
|
+
as="button"
|
77
|
+
>
|
78
|
+
Log Out
|
79
|
+
</Dropdown.Link>
|
80
|
+
</Dropdown.Content>
|
81
|
+
</Dropdown>
|
82
|
+
</div>
|
83
|
+
</div>
|
70
84
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
85
|
+
<div className="-me-2 flex items-center sm:hidden">
|
86
|
+
<button
|
87
|
+
onClick={() =>
|
88
|
+
setShowingNavigationDropdown(
|
89
|
+
(previousState) => !previousState,
|
90
|
+
)
|
91
|
+
}
|
92
|
+
className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out"
|
93
|
+
>
|
94
|
+
<svg
|
95
|
+
className="h-6 w-6"
|
96
|
+
stroke="currentColor"
|
97
|
+
fill="none"
|
98
|
+
viewBox="0 0 24 24"
|
99
|
+
>
|
100
|
+
<path
|
101
|
+
className={
|
102
|
+
!showingNavigationDropdown ? 'inline-flex' : 'hidden'
|
103
|
+
}
|
104
|
+
strokeLinecap="round"
|
105
|
+
strokeLinejoin="round"
|
106
|
+
strokeWidth="2"
|
107
|
+
d="M4 6h16M4 12h16M4 18h16"
|
108
|
+
/>
|
109
|
+
<path
|
110
|
+
className={
|
111
|
+
showingNavigationDropdown ? 'inline-flex' : 'hidden'
|
112
|
+
}
|
113
|
+
strokeLinecap="round"
|
114
|
+
strokeLinejoin="round"
|
115
|
+
strokeWidth="2"
|
116
|
+
d="M6 18L18 6M6 6l12 12"
|
117
|
+
/>
|
118
|
+
</svg>
|
119
|
+
</button>
|
120
|
+
</div>
|
121
|
+
</div>
|
122
|
+
</div>
|
96
123
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
124
|
+
<div
|
125
|
+
className={
|
126
|
+
(showingNavigationDropdown ? 'block' : 'hidden') + ' sm:hidden'
|
127
|
+
}
|
128
|
+
>
|
129
|
+
<div className="pt-2 pb-3 space-y-1">
|
130
|
+
<ResponsiveNavLink
|
131
|
+
href={dashboard_path()}
|
132
|
+
active={pathname.match(/dashboard/) != null}
|
133
|
+
>
|
134
|
+
Dashboard
|
135
|
+
</ResponsiveNavLink>
|
136
|
+
</div>
|
103
137
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
138
|
+
<div className="pt-4 pb-1 border-t border-gray-200">
|
139
|
+
<div className="px-4">
|
140
|
+
<div className="font-medium text-base text-gray-800">
|
141
|
+
{user.name}
|
142
|
+
</div>
|
143
|
+
<div className="font-medium text-sm text-gray-500">
|
144
|
+
{user.email}
|
145
|
+
</div>
|
146
|
+
</div>
|
111
147
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
148
|
+
<div className="mt-3 space-y-1">
|
149
|
+
<ResponsiveNavLink href={profile_edit_path()}>
|
150
|
+
Profile
|
151
|
+
</ResponsiveNavLink>
|
152
|
+
<ResponsiveNavLink method="post" href={logout_path()} as="button">
|
153
|
+
Log Out
|
154
|
+
</ResponsiveNavLink>
|
155
|
+
</div>
|
156
|
+
</div>
|
157
|
+
</div>
|
158
|
+
</nav>
|
121
159
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
160
|
+
{header && (
|
161
|
+
<header className="bg-white shadow">
|
162
|
+
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
163
|
+
{header}
|
164
|
+
</div>
|
165
|
+
</header>
|
166
|
+
)}
|
127
167
|
|
128
|
-
|
129
|
-
|
130
|
-
|
168
|
+
<main>{children}</main>
|
169
|
+
</div>
|
170
|
+
)
|
131
171
|
}
|
@@ -1,19 +1,19 @@
|
|
1
|
-
import ApplicationLogo from '@/Components/ApplicationLogo'
|
2
|
-
import { Link } from '@inertiajs/react'
|
3
|
-
import { PropsWithChildren } from 'react'
|
1
|
+
import ApplicationLogo from '@/Components/ApplicationLogo'
|
2
|
+
import { Link } from '@inertiajs/react'
|
3
|
+
import { PropsWithChildren } from 'react'
|
4
4
|
|
5
5
|
export default function Guest({ children }: PropsWithChildren) {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
return (
|
7
|
+
<div className="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
|
8
|
+
<div>
|
9
|
+
<Link href="/">
|
10
|
+
<ApplicationLogo className="w-20 h-20 fill-current text-gray-500" />
|
11
|
+
</Link>
|
12
|
+
</div>
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
<div className="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg">
|
15
|
+
{children}
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
)
|
19
19
|
}
|
@@ -1,52 +1,55 @@
|
|
1
|
-
import GuestLayout from '@/Layouts/GuestLayout'
|
2
|
-
import InputError from '@/Components/InputError'
|
3
|
-
import PrimaryButton from '@/Components/PrimaryButton'
|
4
|
-
import TextInput from '@/Components/TextInput'
|
5
|
-
import { Head, useForm } from '@inertiajs/react'
|
6
|
-
import { FormEventHandler } from 'react'
|
7
|
-
import { password_email_path } from '@/routes'
|
1
|
+
import GuestLayout from '@/Layouts/GuestLayout'
|
2
|
+
import InputError from '@/Components/InputError'
|
3
|
+
import PrimaryButton from '@/Components/PrimaryButton'
|
4
|
+
import TextInput from '@/Components/TextInput'
|
5
|
+
import { Head, useForm } from '@inertiajs/react'
|
6
|
+
import { FormEventHandler } from 'react'
|
7
|
+
import { password_email_path } from '@/routes'
|
8
8
|
|
9
9
|
export default function ForgotPassword({ status }: { status?: string }) {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
10
|
+
const { data, setData, post, processing, errors } = useForm({
|
11
|
+
email: '',
|
12
|
+
})
|
13
|
+
|
14
|
+
const submit: FormEventHandler = (e) => {
|
15
|
+
e.preventDefault()
|
16
|
+
|
17
|
+
post(password_email_path())
|
18
|
+
}
|
19
|
+
|
20
|
+
return (
|
21
|
+
<GuestLayout>
|
22
|
+
<Head title="Forgot Password" />
|
23
|
+
|
24
|
+
<div className="mb-4 text-sm text-gray-600">
|
25
|
+
Forgot your password? No problem. Just let us know your email address
|
26
|
+
and we will email you a password reset link that will allow you to
|
27
|
+
choose a new one.
|
28
|
+
</div>
|
29
|
+
|
30
|
+
{status && (
|
31
|
+
<div className="mb-4 font-medium text-sm text-green-600">{status}</div>
|
32
|
+
)}
|
33
|
+
|
34
|
+
<form onSubmit={submit}>
|
35
|
+
<TextInput
|
36
|
+
id="email"
|
37
|
+
type="email"
|
38
|
+
name="email"
|
39
|
+
value={data.email}
|
40
|
+
className="mt-1 block w-full"
|
41
|
+
isFocused={true}
|
42
|
+
onChange={(e) => setData('email', e.target.value)}
|
43
|
+
/>
|
44
|
+
|
45
|
+
<InputError message={errors.email} className="mt-2" />
|
46
|
+
|
47
|
+
<div className="flex items-center justify-end mt-4">
|
48
|
+
<PrimaryButton className="ms-4" disabled={processing}>
|
49
|
+
Email Password Reset Link
|
50
|
+
</PrimaryButton>
|
51
|
+
</div>
|
52
|
+
</form>
|
53
|
+
</GuestLayout>
|
54
|
+
)
|
52
55
|
}
|