feat: tempcommit
This commit is contained in:
parent
f813f2351a
commit
b191090f90
4 changed files with 124 additions and 62 deletions
|
@ -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}>
|
||||
|
|
|
@ -69,7 +69,7 @@ export default function LabeledInput({
|
|||
)}
|
||||
type={passwordVisible ? 'text' : type}
|
||||
placeholder={placeholder}
|
||||
value={inputValue}
|
||||
defaultValue={inputValue}
|
||||
id={name}
|
||||
name={name}
|
||||
autoComplete={autocomplete}
|
||||
|
|
|
@ -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 --------------------*/}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue