feat: tempcommit

This commit is contained in:
Maximilian Liebmann 2025-06-30 11:08:56 +02:00
parent f813f2351a
commit b191090f90
4 changed files with 124 additions and 62 deletions

View file

@ -10,7 +10,7 @@ export function IconButton({
icon?: ForwardRefExoticComponent<
Omit<LucideProps, 'ref'> & RefAttributes<SVGSVGElement>
>;
children: React.ReactNode;
children?: React.ReactNode;
} & React.ComponentProps<typeof Button>) {
return (
<Button type='button' variant='secondary' {...props}>

View file

@ -69,7 +69,7 @@ export default function LabeledInput({
)}
type={passwordVisible ? 'text' : type}
placeholder={placeholder}
value={inputValue}
defaultValue={inputValue}
id={name}
name={name}
autoComplete={autocomplete}

View file

@ -29,6 +29,7 @@ import { GroupWrapper } from '../wrappers/group-wrapper';
import ProfilePictureUpload from './profile-picture-upload';
import {
BookKey,
CalendarArrowDown,
CalendarArrowUp,
CalendarCheck,
@ -46,6 +47,14 @@ import {
UserPen,
} from 'lucide-react';
import { IconButton } from '../buttons/icon-button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '../ui/dialog';
export default function SettingsPage() {
const router = useRouter();
@ -53,6 +62,11 @@ export default function SettingsPage() {
const { data } = useGetApiUserMe();
const deleteUser = useDeleteApiUserMe();
// Move password state hooks here
const [currentPassword, setCurrentPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [repeatPassword, setRepeatPassword] = useState('');
const renderSettingsContent = () => {
switch (currentSection) {
case 'general':
@ -109,27 +123,52 @@ export default function SettingsPage() {
{/*-------------------- General Settings --------------------*/}
{/*-------------------- Reset Password --------------------*/}
<GroupWrapper title='Reset Password'>
<div className='flex items-center justify-evenly sm:flex-row flex-col gap-6'>
<div>
<LabeledInput
type='password'
label='Current Password'
icon={FileKey}
></LabeledInput>
</div>
<div>
<LabeledInput
type='password'
label='New Password'
icon={FileKey2}
></LabeledInput>
</div>
<div>
<LabeledInput
type='password'
label='Repeat Password'
icon={RotateCcwKey}
></LabeledInput>
<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-1'>
<LabeledInput
type='password'
label='Current Password'
icon={FileKey}
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
/>
</div>
<div className='flex-1'>
<LabeledInput
type='password'
label='New Password'
icon={FileKey2}
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
/>
</div>
<div className='flex-1'>
<LabeledInput
type='password'
label='Repeat Password'
icon={RotateCcwKey}
value={repeatPassword}
onChange={(e) => setRepeatPassword(e.target.value)}
/>
</div>
<div className='flex items-end'>
<Button
variant={
currentPassword || newPassword || repeatPassword
? 'outline_secondary'
: 'outline_muted'
}
size='icon'
className='w-full md:size-9'
disabled={
!(currentPassword || newPassword || repeatPassword)
}
>
<BookKey className='h-[1.2rem] w-[1.2rem]' />
</Button>
</div>
</div>
</div>
</GroupWrapper>
@ -170,25 +209,49 @@ export default function SettingsPage() {
</div>
</GroupWrapper>
{/*-------------------- Regional Settings --------------------*/}
<GroupWrapper title='DANGER ZONE - INSTANT DELETE - NO CONFIRMATION'>
{/*-------------------- DANGER ZONE --------------------*/}
<GroupWrapper
title='DANGER ZONE'
className='border-destructive'
>
<div className='flex items-center justify-evenly sm:flex-row flex-col gap-6'>
<Button
onClick={() => {
deleteUser.mutate(undefined, {
onSuccess: () => {
router.push('/api/logout');
},
});
}}
variant='destructive'
>
Delete Account
</Button>
<Dialog>
<DialogTrigger>
<Button variant='destructive'>Delete Account</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<div className='space-y-4'>
<DialogTitle>Are you absolutely sure?</DialogTitle>
<div className='space-y-4'>
<DialogDescription>
This action cannot be undone. This will
permanently delete your account and remove your
data from our servers.
</DialogDescription>
<Button
variant='destructive'
onClick={() => {
deleteUser.mutate(undefined, {
onSuccess: () => {
router.push('/api/logout');
},
});
}}
>
Confirm Delete
</Button>
</div>
</div>
</DialogHeader>
</DialogContent>
</Dialog>
<span className='text-sm text-muted-foreground pt-1'>
Permanently delete your account and all associated data.
</span>
</div>
</GroupWrapper>
{/*-------------------- DANGER ZONE --------------------*/}
</CardContent>
</ScrollableSettingsWrapper>
</Card>
@ -236,35 +299,34 @@ export default function SettingsPage() {
</Label>
<Switch id='meetingConfirmations' />
</div>
<div className='space-y-4 grid grid-cols-[1fr_1fr_auto] items-center'>
<div className='flex items-center justify-between space-x-2'>
<Label
htmlFor='enableMeetingReminders'
className='font-normal'
>
Meeting Reminders
</Label>
</div>
<div>
<Label className='text-sm' htmlFor='remindBefore'>
Remind me before
</Label>
<Select>
<SelectTrigger id='remindBefore'>
<SelectValue placeholder='Select reminder time' />
</SelectTrigger>
<SelectContent>
<SelectItem value='15m'>15 minutes</SelectItem>
<SelectItem value='30m'>30 minutes</SelectItem>
<SelectItem value='1h'>1 hour</SelectItem>
<SelectItem value='1d'>1 day</SelectItem>
</SelectContent>
</Select>
</div>
<div className='flex items-center justify-between space-x-2'>
<Label
htmlFor='enableMeetingReminders'
className='font-normal'
>
Meeting Reminders
</Label>
<div>
<Switch id='enableMeetingReminders' />
</div>
</div>
<div className='flex items-center justify-between space-x-2'>
<Label className='font-normal' htmlFor='remindBefore'>
Remind me before
</Label>
<Select>
<SelectTrigger id='remindBefore'>
<SelectValue placeholder='Select reminder time' />
</SelectTrigger>
<SelectContent>
<SelectItem value='15m'>15 minutes</SelectItem>
<SelectItem value='30m'>30 minutes</SelectItem>
<SelectItem value='1h'>1 hour</SelectItem>
<SelectItem value='1d'>1 day</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</GroupWrapper>
{/*-------------------- Meetings --------------------*/}

View file

@ -69,7 +69,7 @@ function DialogContent({
{showCloseButton && (
<DialogPrimitive.Close
data-slot='dialog-close'
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-2 right-2 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span className='sr-only'>Close</span>