diff --git a/src/components/custom-ui/labeled-input.tsx b/src/components/custom-ui/labeled-input.tsx index a3cafcd..c745114 100644 --- a/src/components/custom-ui/labeled-input.tsx +++ b/src/components/custom-ui/labeled-input.tsx @@ -11,6 +11,7 @@ export default function LabeledInput({ subtext, placeholder, value, + defaultValue, name, icon, variantSize = 'default', @@ -31,7 +32,7 @@ export default function LabeledInput({ error?: string; } & React.InputHTMLAttributes) { const [passwordVisible, setPasswordVisible] = React.useState(false); - const [inputValue, setInputValue] = React.useState(value || ''); + const [inputValue, setInputValue] = React.useState(value || defaultValue || ''); const handleInputChange = (e: React.ChangeEvent) => { setInputValue(e.target.value); diff --git a/src/components/misc/settings-page.tsx b/src/components/misc/settings-page.tsx index 60dc7d9..2f51d7b 100644 --- a/src/components/misc/settings-page.tsx +++ b/src/components/misc/settings-page.tsx @@ -22,7 +22,11 @@ import { } from '@/components/ui/select'; import { SettingsDropdown } from '@/components/misc/settings-dropdown'; import { useRouter } from 'next/navigation'; -import { useDeleteApiUserMe, useGetApiUserMe } from '@/generated/api/user/user'; +import { + useDeleteApiUserMe, + useGetApiUserMe, + usePatchApiUserMePassword, +} from '@/generated/api/user/user'; import { ThemePicker } from './theme-picker'; import LabeledInput from '../custom-ui/labeled-input'; import { GroupWrapper } from '../wrappers/group-wrapper'; @@ -55,17 +59,55 @@ import { DialogTitle, DialogTrigger, } from '../ui/dialog'; +import useZodForm from '@/lib/hooks/useZodForm'; +import { updateUserPasswordServerSchema } from '@/app/api/user/me/validation'; export default function SettingsPage() { const router = useRouter(); const [currentSection, setCurrentSection] = useState('general'); const { data } = useGetApiUserMe(); const deleteUser = useDeleteApiUserMe(); + const updatePassword = usePatchApiUserMePassword(); - // Move password state hooks here - const [currentPassword, setCurrentPassword] = useState(''); - const [newPassword, setNewPassword] = useState(''); - const [repeatPassword, setRepeatPassword] = useState(''); + const { handleSubmit, formState, register, setError } = useZodForm( + updateUserPasswordServerSchema, + ); + + const onSubmit = handleSubmit(async (data) => { + await updatePassword.mutateAsync( + { + data: data, + }, + { + onSuccess: () => { + router.refresh(); + }, + onError: (error) => { + if (error instanceof Error) { + setError('root', { + message: error.response?.data.message, + }); + } else { + setError('root', { + message: 'An unknown error occurred.', + }); + } + }, + }, + ); + }); + + if (!data) { + return ( +
+
+
+

Loading Settings...

+
+
+
+ ); + } const renderSettingsContent = () => { switch (currentSection) { @@ -85,7 +127,7 @@ export default function SettingsPage() { type='text' label='First Name' placeholder='First Name' - defaultValue={data?.data.user.first_name ?? ''} + defaultValue={data.data.user.first_name ?? ''} >
@@ -93,7 +135,7 @@ export default function SettingsPage() { type='text' label='Last Name' placeholder='Last Name' - defaultValue={data?.data.user.last_name ?? ''} + defaultValue={data.data.user.last_name ?? ''} >
@@ -102,7 +144,7 @@ export default function SettingsPage() { label='Display Name' icon={UserPen} placeholder='Display Name' - defaultValue={data?.data.user.name} + defaultValue={data.data.user.name} >
@@ -111,7 +153,7 @@ export default function SettingsPage() { label='Email Address' icon={MailOpen} placeholder='Your E-Mail' - defaultValue={data?.data.user.email ?? ''} + defaultValue={data.data.user.email ?? ''} > @@ -123,16 +165,18 @@ export default function SettingsPage() { {/*-------------------- General Settings --------------------*/} {/*-------------------- Reset Password --------------------*/} -
-
- {/* Use the state variables directly */} +
+
setCurrentPassword(e.target.value)} + {...register('current_password')} + error={formState.errors.current_password?.message} />
@@ -140,8 +184,8 @@ export default function SettingsPage() { type='password' label='New Password' icon={FileKey2} - value={newPassword} - onChange={(e) => setNewPassword(e.target.value)} + {...register('new_password')} + error={formState.errors.new_password?.message} />
@@ -149,34 +193,39 @@ export default function SettingsPage() { type='password' label='Repeat Password' icon={RotateCcwKey} - value={repeatPassword} - onChange={(e) => setRepeatPassword(e.target.value)} + {...register('confirm_new_password')} + error={formState.errors.confirm_new_password?.message} />
-
+ + {formState.errors.root && ( +

+ {formState.errors.root.message} +

+ )}
{/*-------------------- Reset Password --------------------*/} {/*-------------------- Profile Picture --------------------*/}
- +
{/*-------------------- Profile Picture --------------------*/} @@ -216,7 +265,7 @@ export default function SettingsPage() { >
- +