Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion resources/js/components/delete-user.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function DeleteUser() {
preserveScroll: true,
}}
onError={() => passwordInput.current?.focus()}
onSubmitComplete={(form) => form.reset()}
resetOnSuccess
className="space-y-6"
>
{({ resetAndClearErrors, processing, errors }) => (
Expand Down
2 changes: 1 addition & 1 deletion resources/js/pages/auth/confirm-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function ConfirmPassword() {
>
<Head title="Confirm password" />

<Form method="post" action={route('password.confirm')} onSubmitComplete={(form) => form.reset('password')}>
<Form method="post" action={route('password.confirm')} resetOnSuccess={['password']}>
{({ processing, errors }) => (
<div className="space-y-6">
<div className="grid gap-2">
Expand Down
2 changes: 1 addition & 1 deletion resources/js/pages/auth/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function Login({ status, canResetPassword }: LoginProps) {
<AuthLayout title="Log in to your account" description="Enter your email and password below to log in">
<Head title="Log in" />

<Form method="post" action={route('login')} onSubmitComplete={(form) => form.reset('password')} className="flex flex-col gap-6">
<Form method="post" action={route('login')} resetOnSuccess={['password']} className="flex flex-col gap-6">
{({ processing, errors }) => (
<>
<div className="grid gap-6">
Expand Down
2 changes: 1 addition & 1 deletion resources/js/pages/auth/register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function Register() {
<Form
method="post"
action={route('register')}
onSubmitComplete={(form) => form.reset('password', 'password_confirmation')}
resetOnSuccess={['password', 'password_confirmation']}
disableWhileProcessing
className="flex flex-col gap-6"
>
Expand Down
2 changes: 1 addition & 1 deletion resources/js/pages/auth/reset-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function ResetPassword({ token, email }: ResetPasswordProps) {
method="post"
action={route('password.store')}
transform={(data) => ({ ...data, token, email })}
onSubmitComplete={(form) => form.reset('password', 'password_confirmation')}
resetOnSuccess={['password', 'password_confirmation']}
>
{({ processing, errors }) => (
<div className="grid gap-6">
Expand Down
179 changes: 86 additions & 93 deletions resources/js/pages/settings/password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import AppLayout from '@/layouts/app-layout';
import SettingsLayout from '@/layouts/settings/layout';
import { type BreadcrumbItem } from '@/types';
import { Transition } from '@headlessui/react';
import { Head, useForm } from '@inertiajs/react';
import { FormEventHandler, useRef } from 'react';
import { Form, Head } from '@inertiajs/react';
import { useRef } from 'react';

import HeadingSmall from '@/components/heading-small';
import { Button } from '@/components/ui/button';
Expand All @@ -22,32 +22,6 @@ export default function Password() {
const passwordInput = useRef<HTMLInputElement>(null);
const currentPasswordInput = useRef<HTMLInputElement>(null);

const { data, setData, errors, put, reset, processing, recentlySuccessful } = useForm({
current_password: '',
password: '',
password_confirmation: '',
});

const updatePassword: FormEventHandler = (e) => {
e.preventDefault();

put(route('password.update'), {
preserveScroll: true,
onSuccess: () => reset(),
onError: (errors) => {
if (errors.password) {
reset('password', 'password_confirmation');
passwordInput.current?.focus();
}

if (errors.current_password) {
reset('current_password');
currentPasswordInput.current?.focus();
}
},
});
};

return (
<AppLayout breadcrumbs={breadcrumbs}>
<Head title="Password settings" />
Expand All @@ -56,71 +30,90 @@ export default function Password() {
<div className="space-y-6">
<HeadingSmall title="Update password" description="Ensure your account is using a long, random password to stay secure" />

<form method="POST" onSubmit={updatePassword} className="space-y-6">
<div className="grid gap-2">
<Label htmlFor="current_password">Current password</Label>

<Input
id="current_password"
ref={currentPasswordInput}
value={data.current_password}
onChange={(e) => setData('current_password', e.target.value)}
type="password"
className="mt-1 block w-full"
autoComplete="current-password"
placeholder="Current password"
/>

<InputError message={errors.current_password} />
</div>

<div className="grid gap-2">
<Label htmlFor="password">New password</Label>

<Input
id="password"
ref={passwordInput}
value={data.password}
onChange={(e) => setData('password', e.target.value)}
type="password"
className="mt-1 block w-full"
autoComplete="new-password"
placeholder="New password"
/>

<InputError message={errors.password} />
</div>

<div className="grid gap-2">
<Label htmlFor="password_confirmation">Confirm password</Label>

<Input
id="password_confirmation"
value={data.password_confirmation}
onChange={(e) => setData('password_confirmation', e.target.value)}
type="password"
className="mt-1 block w-full"
autoComplete="new-password"
placeholder="Confirm password"
/>

<InputError message={errors.password_confirmation} />
</div>

<div className="flex items-center gap-4">
<Button disabled={processing}>Save password</Button>

<Transition
show={recentlySuccessful}
enter="transition ease-in-out"
enterFrom="opacity-0"
leave="transition ease-in-out"
leaveTo="opacity-0"
>
<p className="text-sm text-neutral-600">Saved</p>
</Transition>
</div>
</form>
<Form
method="put"
action={route('password.update')}
options={{
preserveScroll: true,
}}
resetOnError={['password', 'password_confirmation', 'current_password']}
resetOnSuccess
onError={(errors) => {
if (errors.password) {
passwordInput.current?.focus();
}

if (errors.current_password) {
currentPasswordInput.current?.focus();
}
}}
className="space-y-6"
>
{({ errors, processing, recentlySuccessful }) => (
<>
<div className="grid gap-2">
<Label htmlFor="current_password">Current password</Label>

<Input
id="current_password"
ref={currentPasswordInput}
name="current_password"
type="password"
className="mt-1 block w-full"
autoComplete="current-password"
placeholder="Current password"
/>

<InputError message={errors.current_password} />
</div>

<div className="grid gap-2">
<Label htmlFor="password">New password</Label>

<Input
id="password"
ref={passwordInput}
name="password"
type="password"
className="mt-1 block w-full"
autoComplete="new-password"
placeholder="New password"
/>

<InputError message={errors.password} />
</div>

<div className="grid gap-2">
<Label htmlFor="password_confirmation">Confirm password</Label>

<Input
id="password_confirmation"
name="password_confirmation"
type="password"
className="mt-1 block w-full"
autoComplete="new-password"
placeholder="Confirm password"
/>

<InputError message={errors.password_confirmation} />
</div>

<div className="flex items-center gap-4">
<Button disabled={processing}>Save password</Button>

<Transition
show={recentlySuccessful}
enter="transition ease-in-out"
enterFrom="opacity-0"
leave="transition ease-in-out"
leaveTo="opacity-0"
>
<p className="text-sm text-neutral-600">Saved</p>
</Transition>
</div>
</>
)}
</Form>
</div>
</SettingsLayout>
</AppLayout>
Expand Down