feat: tempcommit
This commit is contained in:
parent
b191090f90
commit
f508f26531
2 changed files with 74 additions and 24 deletions
|
@ -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<HTMLInputElement>) {
|
||||
const [passwordVisible, setPasswordVisible] = React.useState(false);
|
||||
const [inputValue, setInputValue] = React.useState(value || '');
|
||||
const [inputValue, setInputValue] = React.useState(value || defaultValue || '');
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setInputValue(e.target.value);
|
||||
|
|
|
@ -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 (
|
||||
<div className='fixed inset-0 flex items-center justify-center p-4 bg-background/50 backdrop-blur-sm'>
|
||||
<div className='rounded-lg border bg-card text-card-foreground shadow-xl max-w-[700px] w-full h-auto max-h-[calc(100vh-2rem)] flex flex-col'>
|
||||
<div className='p-6 border-b'>
|
||||
<h1 className='text-2xl font-semibold'>Loading Settings...</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 ?? ''}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -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 ?? ''}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
|
@ -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}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div className='space-y-2 space-b-2'>
|
||||
|
@ -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 ?? ''}
|
||||
></LabeledInput>
|
||||
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
|
@ -123,16 +165,18 @@ export default function SettingsPage() {
|
|||
{/*-------------------- General Settings --------------------*/}
|
||||
{/*-------------------- Reset Password --------------------*/}
|
||||
<GroupWrapper title='Reset Password'>
|
||||
<div className='flex flex-col sm:flex-row items-center gap-6'>
|
||||
<div className='flex flex-col sm:flex-row gap-6 w-full'>
|
||||
{/* Use the state variables directly */}
|
||||
<div className='flex flex-col items-center gap-6'>
|
||||
<form
|
||||
onSubmit={onSubmit}
|
||||
className='flex flex-col sm:flex-row gap-6 w-full'
|
||||
>
|
||||
<div className='flex-1'>
|
||||
<LabeledInput
|
||||
type='password'
|
||||
label='Current Password'
|
||||
icon={FileKey}
|
||||
value={currentPassword}
|
||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
||||
{...register('current_password')}
|
||||
error={formState.errors.current_password?.message}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
|
@ -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}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
|
@ -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}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex items-end'>
|
||||
<Button
|
||||
variant={
|
||||
currentPassword || newPassword || repeatPassword
|
||||
formState.isValid
|
||||
? 'outline_secondary'
|
||||
: 'outline_muted'
|
||||
}
|
||||
size='icon'
|
||||
className='w-full md:size-9'
|
||||
disabled={
|
||||
!(currentPassword || newPassword || repeatPassword)
|
||||
!formState.isValid || formState.isSubmitting
|
||||
}
|
||||
>
|
||||
<BookKey className='h-[1.2rem] w-[1.2rem]' />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{formState.errors.root && (
|
||||
<p className='text-red-500 text-sm mt-1'>
|
||||
{formState.errors.root.message}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Reset Password --------------------*/}
|
||||
{/*-------------------- Profile Picture --------------------*/}
|
||||
<GroupWrapper title='Profile Picture'>
|
||||
<div className='space-y-2 grid grid-cols-[1fr_auto]'>
|
||||
<ProfilePictureUpload className='file:border file:rounded-md file:hover:bg-disabled-destructive' />
|
||||
<ProfilePictureUpload />
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Profile Picture --------------------*/}
|
||||
|
@ -216,7 +265,7 @@ export default function SettingsPage() {
|
|||
>
|
||||
<div className='flex items-center justify-evenly sm:flex-row flex-col gap-6'>
|
||||
<Dialog>
|
||||
<DialogTrigger>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant='destructive'>Delete Account</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue