kaze 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kaze/commands/install_command.rb +18 -4
  3. data/lib/kaze/commands/installs_hotwire_stack.rb +5 -2
  4. data/lib/kaze/commands/installs_inertia_stacks.rb +13 -3
  5. data/lib/kaze/version.rb +1 -1
  6. data/stubs/default/app/forms/auth/login_form.rb +2 -8
  7. data/stubs/default/app/forms/update_profile_information_form.rb +1 -1
  8. data/stubs/default/app/models/auth.rb +57 -0
  9. data/stubs/default/app/models/current.rb +1 -1
  10. data/stubs/default/app/validators/current_password_validator.rb +1 -1
  11. data/stubs/default/app/views/layouts/mailer.html.erb +367 -372
  12. data/stubs/default/app/views/layouts/mailer.text.erb +1 -4
  13. data/stubs/default/app/views/user_mailer/reset_password.html.erb +21 -26
  14. data/stubs/default/test/factories/users.rb +7 -0
  15. data/stubs/default/test/integration/auth/authentication_test.rb +43 -0
  16. data/stubs/default/test/integration/auth/password_reset_test.rb +41 -0
  17. data/stubs/default/test/integration/auth/registration_test.rb +21 -0
  18. data/stubs/default/test/integration/password_update_test.rb +28 -0
  19. data/stubs/default/test/integration/profile_test.rb +51 -0
  20. data/stubs/default/test/test_helper.rb +38 -0
  21. data/stubs/hotwire/app/components/dropdown_component.html.erb +17 -18
  22. data/stubs/hotwire/app/components/modal_component.html.erb +55 -59
  23. data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
  24. data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +10 -7
  25. data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +3 -1
  26. data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +3 -1
  27. data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +4 -2
  28. data/stubs/hotwire/app/controllers/concerns/authenticate.rb +5 -20
  29. data/stubs/hotwire/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
  30. data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +9 -0
  31. data/stubs/hotwire/app/controllers/password_controller.rb +1 -1
  32. data/stubs/hotwire/app/controllers/profile_controller.rb +6 -4
  33. data/stubs/hotwire/app/controllers/welcome_controller.rb +1 -1
  34. data/stubs/hotwire/app/javascript/application.js +3 -3
  35. data/stubs/hotwire/app/views/auth/forgot_password.html.erb +12 -17
  36. data/stubs/hotwire/app/views/auth/login.html.erb +0 -9
  37. data/stubs/hotwire/app/views/auth/register.html.erb +0 -13
  38. data/stubs/hotwire/app/views/auth/reset_password.html.erb +0 -7
  39. data/stubs/hotwire/app/views/dashboard/index.html.erb +9 -10
  40. data/stubs/hotwire/app/views/layouts/_navigation.html.erb +77 -87
  41. data/stubs/hotwire/app/views/layouts/application.html.erb +0 -9
  42. data/stubs/hotwire/app/views/layouts/guest.html.erb +0 -6
  43. data/stubs/hotwire/app/views/profile/edit.html.erb +19 -22
  44. data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +32 -42
  45. data/stubs/hotwire/app/views/profile/partials/_update_password_form.html.erb +42 -55
  46. data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +36 -46
  47. data/stubs/hotwire/app/views/welcome/index.html.erb +34 -46
  48. data/stubs/hotwire/config/tailwind.config.js +2 -2
  49. data/stubs/inertia-common/app/controllers/application_controller.rb +1 -0
  50. data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +10 -7
  51. data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +3 -1
  52. data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +3 -1
  53. data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +4 -2
  54. data/stubs/inertia-common/app/controllers/concerns/authenticate.rb +5 -20
  55. data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +1 -1
  56. data/stubs/inertia-common/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
  57. data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +9 -0
  58. data/stubs/inertia-common/app/controllers/password_controller.rb +1 -1
  59. data/stubs/inertia-common/app/controllers/profile_controller.rb +5 -3
  60. data/stubs/inertia-common/app/controllers/welcome_controller.rb +1 -1
  61. data/stubs/inertia-common/test/integration/password_update_test.rb +28 -0
  62. data/stubs/inertia-common/test/integration/profile_test.rb +51 -0
  63. data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +13 -9
  64. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +12 -12
  65. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +20 -15
  66. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +115 -88
  67. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +14 -7
  68. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +15 -7
  69. data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +60 -60
  70. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +21 -16
  71. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +20 -15
  72. data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +19 -14
  73. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +22 -16
  74. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +32 -24
  75. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +157 -117
  76. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +15 -15
  77. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -49
  78. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +90 -82
  79. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -115
  80. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +63 -60
  81. data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +23 -17
  82. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +31 -27
  83. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +109 -99
  84. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +121 -113
  85. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +76 -69
  86. data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +87 -63
  87. data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +32 -25
  88. data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +0 -4
  89. data/stubs/inertia-react-ts/config/tailwind.config.js +2 -2
  90. data/stubs/inertia-react-ts/vite.config.ts +2 -5
  91. data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +10 -6
  92. data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +18 -18
  93. data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +5 -5
  94. data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +60 -57
  95. data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +9 -9
  96. data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +7 -7
  97. data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +6 -6
  98. data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +84 -74
  99. data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +12 -12
  100. data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +5 -5
  101. data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +12 -12
  102. data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +13 -13
  103. data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +13 -13
  104. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +168 -136
  105. data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +15 -13
  106. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +56 -49
  107. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +78 -72
  108. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +101 -97
  109. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +71 -68
  110. data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -14
  111. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +34 -30
  112. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +87 -83
  113. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +105 -98
  114. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +69 -59
  115. data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +74 -47
  116. data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +0 -4
  117. data/stubs/inertia-vue-ts/config/tailwind.config.js +2 -2
  118. data/stubs/inertia-vue-ts/vite.config.ts +2 -5
  119. metadata +18 -6
  120. data/stubs/hotwire/bin/vite +0 -27
  121. data/stubs/inertia-common/Procfile.dev +0 -3
  122. /data/stubs/{hotwire → default}/Procfile.dev +0 -0
  123. /data/stubs/hotwire/app/javascript/{alpinejs.js → alpinejs.stub} +0 -0
@@ -1,12 +1,16 @@
1
- import { SVGAttributes } from 'react';
1
+ import { SVGAttributes } from 'react'
2
2
 
3
3
  export default function ApplicationLogo(props: SVGAttributes<SVGElement>) {
4
- return (
5
- <svg {...props} viewBox="0 -6 32 32" xmlns="http://www.w3.org/2000/svg">
6
- <g fill="none" fillRule="evenodd">
7
- <path d="M0-6h32v32H0z"/>
8
- <path fill="#c00" fillRule="nonzero" d="M.985 19.636s.422-4.163 3.375-9.087c2.954-4.924 7.99-8.65 12.083-9.017 8.144-.816 15.46 6.485 15.46 6.485s-.24.168-.494.38C23.42 2.49 18.54 5.274 17.005 6.02c-7.033 3.925-4.91 13.616-4.91 13.616H.987zM24.137 2.32c-.45-.182-.9-.35-1.364-.505l.056-.93c.885.254 1.237.423 1.363.493l-.056.943zM22.8 5.304c.45.028.915.084 1.393.183l-.056.872c-.464-.1-.928-.155-1.392-.17l.056-.885zM17.597.913c-.407 0-.815.015-1.223.058l-.268-.83c.465-.056.915-.084 1.35-.084l.282.858h-.14zm.676 5.178c.35-.154.76-.31 1.237-.45l.31.93c-.41.125-.817.294-1.225.49l-.323-.97zm-6.386-3.7c-.366.184-.718.395-1.083.62l-.647-.985c.38-.225.745-.42 1.097-.604l.633.97zm2.883 6.33c.252-.323.548-.646.87-.942l.634.957c-.31.323-.59.647-.83 1L14.77 8.72zm-2.04 4.53c.112-.506.24-1.027.422-1.547l1.012.802c-.14.548-.24 1.097-.295 1.645l-1.14-.9zM6.57 6.57c-.34.35-.662.73-.958 1.11L4.53 6.752c.323-.352.674-.704 1.04-1.055l1 .872zm-4.25 6.286c-.224.52-.52 1.21-.702 1.688L0 13.954c.14-.38.436-1.084.703-1.69l1.618.592zm10.2 3.967l1.518.548c.084.663.21 1.28.337 1.83l-1.688-.605c-.07-.422-.14-1.027-.168-1.772z"/>
9
- </g>
10
- </svg>
11
- );
4
+ return (
5
+ <svg {...props} viewBox="0 -6 32 32" xmlns="http://www.w3.org/2000/svg">
6
+ <g fill="none" fillRule="evenodd">
7
+ <path d="M0-6h32v32H0z" />
8
+ <path
9
+ fill="#c00"
10
+ fillRule="nonzero"
11
+ d="M.985 19.636s.422-4.163 3.375-9.087c2.954-4.924 7.99-8.65 12.083-9.017 8.144-.816 15.46 6.485 15.46 6.485s-.24.168-.494.38C23.42 2.49 18.54 5.274 17.005 6.02c-7.033 3.925-4.91 13.616-4.91 13.616H.987zM24.137 2.32c-.45-.182-.9-.35-1.364-.505l.056-.93c.885.254 1.237.423 1.363.493l-.056.943zM22.8 5.304c.45.028.915.084 1.393.183l-.056.872c-.464-.1-.928-.155-1.392-.17l.056-.885zM17.597.913c-.407 0-.815.015-1.223.058l-.268-.83c.465-.056.915-.084 1.35-.084l.282.858h-.14zm.676 5.178c.35-.154.76-.31 1.237-.45l.31.93c-.41.125-.817.294-1.225.49l-.323-.97zm-6.386-3.7c-.366.184-.718.395-1.083.62l-.647-.985c.38-.225.745-.42 1.097-.604l.633.97zm2.883 6.33c.252-.323.548-.646.87-.942l.634.957c-.31.323-.59.647-.83 1L14.77 8.72zm-2.04 4.53c.112-.506.24-1.027.422-1.547l1.012.802c-.14.548-.24 1.097-.295 1.645l-1.14-.9zM6.57 6.57c-.34.35-.662.73-.958 1.11L4.53 6.752c.323-.352.674-.704 1.04-1.055l1 .872zm-4.25 6.286c-.224.52-.52 1.21-.702 1.688L0 13.954c.14-.38.436-1.084.703-1.69l1.618.592zm10.2 3.967l1.518.548c.084.663.21 1.28.337 1.83l-1.688-.605c-.07-.422-.14-1.027-.168-1.772z"
12
+ />
13
+ </g>
14
+ </svg>
15
+ )
12
16
  }
@@ -1,14 +1,14 @@
1
- import { InputHTMLAttributes } from 'react';
1
+ import { InputHTMLAttributes } from 'react'
2
2
 
3
- export default function Checkbox({ className = '', ...props }: InputHTMLAttributes<HTMLInputElement>) {
4
- return (
5
- <input
6
- {...props}
7
- type="checkbox"
8
- className={
9
- 'rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 ' +
10
- className
11
- }
12
- />
13
- );
3
+ export default function Checkbox({
4
+ className = '',
5
+ ...props
6
+ }: InputHTMLAttributes<HTMLInputElement>) {
7
+ return (
8
+ <input
9
+ {...props}
10
+ type="checkbox"
11
+ className={`rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 ${className}`}
12
+ />
13
+ )
14
14
  }
@@ -1,17 +1,22 @@
1
- import { ButtonHTMLAttributes } from 'react';
1
+ import { ButtonHTMLAttributes } from 'react'
2
2
 
3
- export default function DangerButton({ className = '', disabled, children, ...props }: ButtonHTMLAttributes<HTMLButtonElement>) {
4
- return (
5
- <button
6
- {...props}
7
- className={
8
- `inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
9
- disabled && 'opacity-25'
10
- } ` + className
11
- }
12
- disabled={disabled}
13
- >
14
- {children}
15
- </button>
16
- );
3
+ export default function DangerButton({
4
+ className = '',
5
+ disabled,
6
+ children,
7
+ ...props
8
+ }: ButtonHTMLAttributes<HTMLButtonElement>) {
9
+ return (
10
+ <button
11
+ {...props}
12
+ className={
13
+ `inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
14
+ disabled && 'opacity-25'
15
+ } ${className}`
16
+ }
17
+ disabled={disabled}
18
+ >
19
+ {children}
20
+ </button>
21
+ )
17
22
  }
@@ -1,99 +1,126 @@
1
- import { useState, createContext, useContext, Fragment, PropsWithChildren, Dispatch, SetStateAction } from 'react';
2
- import { Link, InertiaLinkProps } from '@inertiajs/react';
3
- import { Transition } from '@headlessui/react';
1
+ import {
2
+ useState,
3
+ createContext,
4
+ useContext,
5
+ Fragment,
6
+ PropsWithChildren,
7
+ Dispatch,
8
+ SetStateAction,
9
+ } from 'react'
10
+ import { Link, InertiaLinkProps } from '@inertiajs/react'
11
+ import { Transition } from '@headlessui/react'
4
12
 
5
13
  const DropDownContext = createContext<{
6
- open: boolean;
7
- setOpen: Dispatch<SetStateAction<boolean>>;
8
- toggleOpen: () => void;
14
+ open: boolean
15
+ setOpen: Dispatch<SetStateAction<boolean>>
16
+ toggleOpen: () => void
9
17
  }>({
10
- open: false,
11
- setOpen: () => {},
12
- toggleOpen: () => {},
13
- });
18
+ open: false,
19
+ setOpen: () => {},
20
+ toggleOpen: () => {},
21
+ })
14
22
 
15
23
  const Dropdown = ({ children }: PropsWithChildren) => {
16
- const [open, setOpen] = useState(false);
24
+ const [open, setOpen] = useState(false)
17
25
 
18
- const toggleOpen = () => {
19
- setOpen((previousState) => !previousState);
20
- };
26
+ const toggleOpen = () => {
27
+ setOpen((previousState) => !previousState)
28
+ }
21
29
 
22
- return (
23
- <DropDownContext.Provider value={{ open, setOpen, toggleOpen }}>
24
- <div className="relative">{children}</div>
25
- </DropDownContext.Provider>
26
- );
27
- };
30
+ return (
31
+ <DropDownContext.Provider value={{ open, setOpen, toggleOpen }}>
32
+ <div className="relative">{children}</div>
33
+ </DropDownContext.Provider>
34
+ )
35
+ }
28
36
 
29
37
  const Trigger = ({ children }: PropsWithChildren) => {
30
- const { open, setOpen, toggleOpen } = useContext(DropDownContext);
31
-
32
- return (
33
- <>
34
- <div onClick={toggleOpen}>{children}</div>
35
-
36
- {open && <div className="fixed inset-0 z-40" onClick={() => setOpen(false)}></div>}
37
- </>
38
- );
39
- };
40
-
41
- const Content = ({ align = 'right', width = '48', contentClasses = 'py-1 bg-white dark:bg-gray-700', children }: PropsWithChildren<{ align?: 'left'|'right', width?: '48', contentClasses?: string }>) => {
42
- const { open, setOpen } = useContext(DropDownContext);
43
-
44
- let alignmentClasses = 'origin-top';
45
-
46
- if (align === 'left') {
47
- alignmentClasses = 'ltr:origin-top-left rtl:origin-top-right start-0';
48
- } else if (align === 'right') {
49
- alignmentClasses = 'ltr:origin-top-right rtl:origin-top-left end-0';
50
- }
51
-
52
- let widthClasses = '';
53
-
54
- if (width === '48') {
55
- widthClasses = 'w-48';
56
- }
57
-
58
- return (
59
- <>
60
- <Transition
61
- as={Fragment}
62
- show={open}
63
- enter="transition ease-out duration-200"
64
- enterFrom="opacity-0 scale-95"
65
- enterTo="opacity-100 scale-100"
66
- leave="transition ease-in duration-75"
67
- leaveFrom="opacity-100 scale-100"
68
- leaveTo="opacity-0 scale-95"
69
- >
70
- <div
71
- className={`absolute z-50 mt-2 rounded-md shadow-lg ${alignmentClasses} ${widthClasses}`}
72
- onClick={() => setOpen(false)}
73
- >
74
- <div className={`rounded-md ring-1 ring-black ring-opacity-5 ` + contentClasses}>{children}</div>
75
- </div>
76
- </Transition>
77
- </>
78
- );
79
- };
80
-
81
- const DropdownLink = ({ className = '', children, ...props }: InertiaLinkProps) => {
82
- return (
83
- <Link
84
- {...props}
85
- className={
86
- 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-800 transition duration-150 ease-in-out ' +
87
- className
88
- }
38
+ const { open, setOpen, toggleOpen } = useContext(DropDownContext)
39
+
40
+ return (
41
+ <>
42
+ <div onClick={toggleOpen}>{children}</div>
43
+
44
+ {open && (
45
+ <div
46
+ className="fixed inset-0 z-40"
47
+ onClick={() => setOpen(false)}
48
+ ></div>
49
+ )}
50
+ </>
51
+ )
52
+ }
53
+
54
+ const Content = ({
55
+ align = 'right',
56
+ width = '48',
57
+ contentClasses = 'py-1 bg-white dark:bg-gray-700',
58
+ children,
59
+ }: PropsWithChildren<{
60
+ align?: 'left' | 'right'
61
+ width?: '48'
62
+ contentClasses?: string
63
+ }>) => {
64
+ const { open, setOpen } = useContext(DropDownContext)
65
+
66
+ let alignmentClasses = 'origin-top'
67
+
68
+ if (align === 'left') {
69
+ alignmentClasses = 'ltr:origin-top-left rtl:origin-top-right start-0'
70
+ } else if (align === 'right') {
71
+ alignmentClasses = 'ltr:origin-top-right rtl:origin-top-left end-0'
72
+ }
73
+
74
+ let widthClasses = ''
75
+
76
+ if (width === '48') {
77
+ widthClasses = 'w-48'
78
+ }
79
+
80
+ return (
81
+ <>
82
+ <Transition
83
+ as={Fragment}
84
+ show={open}
85
+ enter="transition ease-out duration-200"
86
+ enterFrom="opacity-0 scale-95"
87
+ enterTo="opacity-100 scale-100"
88
+ leave="transition ease-in duration-75"
89
+ leaveFrom="opacity-100 scale-100"
90
+ leaveTo="opacity-0 scale-95"
91
+ >
92
+ <div
93
+ className={`absolute z-50 mt-2 rounded-md shadow-lg ${alignmentClasses} ${widthClasses}`}
94
+ onClick={() => setOpen(false)}
89
95
  >
96
+ <div
97
+ className={`rounded-md ring-1 ring-black ring-opacity-5 ${contentClasses}`}
98
+ >
90
99
  {children}
91
- </Link>
92
- );
93
- };
94
-
95
- Dropdown.Trigger = Trigger;
96
- Dropdown.Content = Content;
97
- Dropdown.Link = DropdownLink;
98
-
99
- export default Dropdown;
100
+ </div>
101
+ </div>
102
+ </Transition>
103
+ </>
104
+ )
105
+ }
106
+
107
+ const DropdownLink = ({
108
+ className = '',
109
+ children,
110
+ ...props
111
+ }: InertiaLinkProps) => {
112
+ return (
113
+ <Link
114
+ {...props}
115
+ className={`block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-800 transition duration-150 ease-in-out ${className}`}
116
+ >
117
+ {children}
118
+ </Link>
119
+ )
120
+ }
121
+
122
+ Dropdown.Trigger = Trigger
123
+ Dropdown.Content = Content
124
+ Dropdown.Link = DropdownLink
125
+
126
+ export default Dropdown
@@ -1,9 +1,16 @@
1
- import { HTMLAttributes } from 'react';
1
+ import { HTMLAttributes } from 'react'
2
2
 
3
- export default function InputError({ message, className = '', ...props }: HTMLAttributes<HTMLParagraphElement> & { message?: string }) {
4
- return message ? (
5
- <p {...props} className={'text-sm text-red-600 dark:text-red-400 ' + className}>
6
- {message}
7
- </p>
8
- ) : null;
3
+ export default function InputError({
4
+ message,
5
+ className = '',
6
+ ...props
7
+ }: HTMLAttributes<HTMLParagraphElement> & { message?: string }) {
8
+ return message ? (
9
+ <p
10
+ {...props}
11
+ className={`text-sm text-red-600 dark:text-red-400 ${className}`}
12
+ >
13
+ {message}
14
+ </p>
15
+ ) : null
9
16
  }
@@ -1,9 +1,17 @@
1
- import { LabelHTMLAttributes } from 'react';
1
+ import { LabelHTMLAttributes } from 'react'
2
2
 
3
- export default function InputLabel({ value, className = '', children, ...props }: LabelHTMLAttributes<HTMLLabelElement> & { value?: string }) {
4
- return (
5
- <label {...props} className={`block font-medium text-sm text-gray-700 dark:text-gray-300 ` + className}>
6
- {value ? value : children}
7
- </label>
8
- );
3
+ export default function InputLabel({
4
+ value,
5
+ className = '',
6
+ children,
7
+ ...props
8
+ }: LabelHTMLAttributes<HTMLLabelElement> & { value?: string }) {
9
+ return (
10
+ <label
11
+ {...props}
12
+ className={`block font-medium text-sm text-gray-700 dark:text-gray-300 ${className}`}
13
+ >
14
+ {value ? value : children}
15
+ </label>
16
+ )
9
17
  }
@@ -1,68 +1,68 @@
1
- import { Fragment, PropsWithChildren } from 'react';
2
- import { Dialog, Transition } from '@headlessui/react';
1
+ import { Fragment, PropsWithChildren } from 'react'
2
+ import { Dialog, Transition } from '@headlessui/react'
3
3
 
4
4
  export default function Modal({
5
- children,
6
- show = false,
7
- maxWidth = '2xl',
8
- closeable = true,
9
- onClose = () => {},
5
+ children,
6
+ show = false,
7
+ maxWidth = '2xl',
8
+ closeable = true,
9
+ onClose = () => {},
10
10
  }: PropsWithChildren<{
11
- show: boolean;
12
- maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
13
- closeable?: boolean;
14
- onClose: CallableFunction;
11
+ show: boolean
12
+ maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
13
+ closeable?: boolean
14
+ onClose: CallableFunction
15
15
  }>) {
16
- const close = () => {
17
- if (closeable) {
18
- onClose();
19
- }
20
- };
16
+ const close = () => {
17
+ if (closeable) {
18
+ onClose()
19
+ }
20
+ }
21
21
 
22
- const maxWidthClass = {
23
- sm: 'sm:max-w-sm',
24
- md: 'sm:max-w-md',
25
- lg: 'sm:max-w-lg',
26
- xl: 'sm:max-w-xl',
27
- '2xl': 'sm:max-w-2xl',
28
- }[maxWidth];
22
+ const maxWidthClass = {
23
+ sm: 'sm:max-w-sm',
24
+ md: 'sm:max-w-md',
25
+ lg: 'sm:max-w-lg',
26
+ xl: 'sm:max-w-xl',
27
+ '2xl': 'sm:max-w-2xl',
28
+ }[maxWidth]
29
29
 
30
- return (
31
- <Transition show={show} as={Fragment} leave="duration-200">
32
- <Dialog
33
- as="div"
34
- id="modal"
35
- className="fixed inset-0 flex overflow-y-auto px-4 py-6 sm:px-0 items-center z-50 transform transition-all"
36
- onClose={close}
37
- >
38
- <Transition.Child
39
- as={Fragment}
40
- enter="ease-out duration-300"
41
- enterFrom="opacity-0"
42
- enterTo="opacity-100"
43
- leave="ease-in duration-200"
44
- leaveFrom="opacity-100"
45
- leaveTo="opacity-0"
46
- >
47
- <div className="absolute inset-0 bg-gray-500/75 dark:bg-gray-900/75" />
48
- </Transition.Child>
30
+ return (
31
+ <Transition show={show} as={Fragment} leave="duration-200">
32
+ <Dialog
33
+ as="div"
34
+ id="modal"
35
+ className="fixed inset-0 flex overflow-y-auto px-4 py-6 sm:px-0 items-center z-50 transform transition-all"
36
+ onClose={close}
37
+ >
38
+ <Transition.Child
39
+ as={Fragment}
40
+ enter="ease-out duration-300"
41
+ enterFrom="opacity-0"
42
+ enterTo="opacity-100"
43
+ leave="ease-in duration-200"
44
+ leaveFrom="opacity-100"
45
+ leaveTo="opacity-0"
46
+ >
47
+ <div className="absolute inset-0 bg-gray-500/75 dark:bg-gray-900/75" />
48
+ </Transition.Child>
49
49
 
50
- <Transition.Child
51
- as={Fragment}
52
- enter="ease-out duration-300"
53
- enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
54
- enterTo="opacity-100 translate-y-0 sm:scale-100"
55
- leave="ease-in duration-200"
56
- leaveFrom="opacity-100 translate-y-0 sm:scale-100"
57
- leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
58
- >
59
- <Dialog.Panel
60
- className={`mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto ${maxWidthClass}`}
61
- >
62
- {children}
63
- </Dialog.Panel>
64
- </Transition.Child>
65
- </Dialog>
66
- </Transition>
67
- );
50
+ <Transition.Child
51
+ as={Fragment}
52
+ enter="ease-out duration-300"
53
+ enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
54
+ enterTo="opacity-100 translate-y-0 sm:scale-100"
55
+ leave="ease-in duration-200"
56
+ leaveFrom="opacity-100 translate-y-0 sm:scale-100"
57
+ leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
58
+ >
59
+ <Dialog.Panel
60
+ className={`mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto ${maxWidthClass}`}
61
+ >
62
+ {children}
63
+ </Dialog.Panel>
64
+ </Transition.Child>
65
+ </Dialog>
66
+ </Transition>
67
+ )
68
68
  }
@@ -1,18 +1,23 @@
1
- import { Link, InertiaLinkProps } from '@inertiajs/react';
1
+ import { Link, InertiaLinkProps } from '@inertiajs/react'
2
2
 
3
- export default function NavLink({ active = false, className = '', children, ...props }: InertiaLinkProps & { active: boolean }) {
4
- return (
5
- <Link
6
- {...props}
7
- className={
8
- 'inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium leading-5 transition duration-150 ease-in-out focus:outline-none ' +
9
- (active
10
- ? 'border-indigo-400 dark:border-indigo-600 text-gray-900 dark:text-gray-100 focus:border-indigo-700 '
11
- : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 ') +
12
- className
13
- }
14
- >
15
- {children}
16
- </Link>
17
- );
3
+ export default function NavLink({
4
+ active = false,
5
+ className = '',
6
+ children,
7
+ ...props
8
+ }: InertiaLinkProps & { active: boolean }) {
9
+ return (
10
+ <Link
11
+ {...props}
12
+ className={
13
+ `inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium leading-5 transition duration-150 ease-in-out focus:outline-none ${
14
+ active
15
+ ? 'border-indigo-400 dark:border-indigo-600 text-gray-900 dark:text-gray-100 focus:border-indigo-700 '
16
+ : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 '
17
+ } ${className}`
18
+ }
19
+ >
20
+ {children}
21
+ </Link>
22
+ )
18
23
  }
@@ -1,17 +1,22 @@
1
- import { ButtonHTMLAttributes } from 'react';
1
+ import { ButtonHTMLAttributes } from 'react'
2
2
 
3
- export default function PrimaryButton({ className = '', disabled, children, ...props }: ButtonHTMLAttributes<HTMLButtonElement>) {
4
- return (
5
- <button
6
- {...props}
7
- className={
8
- `inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
9
- disabled && 'opacity-25'
10
- } ` + className
11
- }
12
- disabled={disabled}
13
- >
14
- {children}
15
- </button>
16
- );
3
+ export default function PrimaryButton({
4
+ className = '',
5
+ disabled,
6
+ children,
7
+ ...props
8
+ }: ButtonHTMLAttributes<HTMLButtonElement>) {
9
+ return (
10
+ <button
11
+ {...props}
12
+ className={
13
+ `inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
14
+ disabled && 'opacity-25'
15
+ } ${className}`
16
+ }
17
+ disabled={disabled}
18
+ >
19
+ {children}
20
+ </button>
21
+ )
17
22
  }
@@ -1,16 +1,21 @@
1
- import { Link, InertiaLinkProps } from '@inertiajs/react';
1
+ import { Link, InertiaLinkProps } from '@inertiajs/react'
2
2
 
3
- export default function ResponsiveNavLink({ active = false, className = '', children, ...props }: InertiaLinkProps & { active?: boolean }) {
4
- return (
5
- <Link
6
- {...props}
7
- className={`w-full flex items-start ps-3 pe-4 py-2 border-l-4 ${
8
- active
9
- ? 'border-indigo-400 dark:border-indigo-600 text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 focus:text-indigo-800 dark:focus:text-indigo-200 focus:bg-indigo-100 dark:focus:bg-indigo-900 focus:border-indigo-700 dark:focus:border-indigo-300'
10
- : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-gray-300 dark:hover:border-gray-600 focus:text-gray-800 dark:focus:text-gray-200 focus:bg-gray-50 dark:focus:bg-gray-700 focus:border-gray-300 dark:focus:border-gray-600'
11
- } text-base font-medium focus:outline-none transition duration-150 ease-in-out ${className}`}
12
- >
13
- {children}
14
- </Link>
15
- );
3
+ export default function ResponsiveNavLink({
4
+ active = false,
5
+ className = '',
6
+ children,
7
+ ...props
8
+ }: InertiaLinkProps & { active?: boolean }) {
9
+ return (
10
+ <Link
11
+ {...props}
12
+ className={`w-full flex items-start ps-3 pe-4 py-2 border-l-4 ${
13
+ active
14
+ ? 'border-indigo-400 dark:border-indigo-600 text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 focus:text-indigo-800 dark:focus:text-indigo-200 focus:bg-indigo-100 dark:focus:bg-indigo-900 focus:border-indigo-700 dark:focus:border-indigo-300'
15
+ : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-gray-300 dark:hover:border-gray-600 focus:text-gray-800 dark:focus:text-gray-200 focus:bg-gray-50 dark:focus:bg-gray-700 focus:border-gray-300 dark:focus:border-gray-600'
16
+ } text-base font-medium focus:outline-none transition duration-150 ease-in-out ${className}`}
17
+ >
18
+ {children}
19
+ </Link>
20
+ )
16
21
  }