feat: tempcommit (broken input)
This commit is contained in:
parent
7d2d5c55e8
commit
fa3b2da69c
6 changed files with 328 additions and 202 deletions
|
@ -9,7 +9,7 @@ import {
|
|||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card';
|
||||
import { Input } from '@/components/ui/input';
|
||||
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { ScrollableSettingsWrapper } from '@/components/wrappers/settings-scroll';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
|
@ -28,8 +28,23 @@ import LabeledInput from '../custom-ui/labeled-input';
|
|||
import { GroupWrapper } from '../wrappers/group-wrapper';
|
||||
|
||||
import ProfilePictureUpload from './profile-picture-upload';
|
||||
import { LogOut } from 'lucide-react';
|
||||
import { signOut } from '@/auth';
|
||||
import {
|
||||
CalendarArrowDown,
|
||||
CalendarArrowUp,
|
||||
CalendarCheck,
|
||||
CalendarClock,
|
||||
CalendarCog,
|
||||
CalendarPlus,
|
||||
CalendarPlus2,
|
||||
ClockAlert,
|
||||
ClockFading,
|
||||
FileKey,
|
||||
FileKey2,
|
||||
MailOpen,
|
||||
RotateCcwKey,
|
||||
UserLock,
|
||||
} from 'lucide-react';
|
||||
import { IconButton } from '../buttons/icon-button';
|
||||
|
||||
export default function SettingsPage() {
|
||||
const router = useRouter();
|
||||
|
@ -46,7 +61,8 @@ export default function SettingsPage() {
|
|||
<CardHeader>
|
||||
<CardTitle>Account Settings</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6 mt-2'>
|
||||
<CardContent className='space-y-6 my-2'>
|
||||
{/*-------------------- General Settings --------------------*/}
|
||||
<GroupWrapper title='General Settings'>
|
||||
<div className='space-y-4'>
|
||||
<div>
|
||||
|
@ -77,6 +93,7 @@ export default function SettingsPage() {
|
|||
<LabeledInput
|
||||
type='email'
|
||||
label='Email Address'
|
||||
icon={MailOpen}
|
||||
placeholder='Your E-Mail'
|
||||
defaultValue={data?.data.user.email ?? ''}
|
||||
></LabeledInput>
|
||||
|
@ -87,39 +104,42 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- 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'
|
||||
placeholder='Current Password'
|
||||
defaultValue={data?.data.user.first_name ?? ''}
|
||||
icon={FileKey}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div>
|
||||
<LabeledInput
|
||||
type='password'
|
||||
label='New Password'
|
||||
placeholder='New Password'
|
||||
defaultValue={data?.data.user.first_name ?? ''}
|
||||
icon={FileKey2}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div>
|
||||
<LabeledInput
|
||||
type='password'
|
||||
label='Repeat Password'
|
||||
placeholder='Repeat Password'
|
||||
defaultValue={data?.data.user.first_name ?? ''}
|
||||
icon={RotateCcwKey}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
</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' />
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Profile Picture --------------------*/}
|
||||
{/*-------------------- Regional Settings --------------------*/}
|
||||
<GroupWrapper title='Regional Settings'>
|
||||
<div className='space-y-2 grid sm:grid-cols-[1fr_auto] sm:flex-row gap-4'>
|
||||
<div className='grid gap-1'>
|
||||
|
@ -127,6 +147,7 @@ export default function SettingsPage() {
|
|||
type='text'
|
||||
label='Timezone'
|
||||
placeholder='Europe/Berlin'
|
||||
icon={CalendarClock}
|
||||
defaultValue={data?.data.user.timezone ?? ''}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
|
@ -146,23 +167,26 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
<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>
|
||||
<span className='text-sm text-muted-foreground pt-1'>
|
||||
Permanently delete your account and all associated data.
|
||||
</span>
|
||||
</div>
|
||||
{/*-------------------- Regional Settings --------------------*/}
|
||||
<GroupWrapper title='DANGER ZONE - INSTANT DELETE - NO CONFIRMATION'>
|
||||
<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>
|
||||
<span className='text-sm text-muted-foreground pt-1'>
|
||||
Permanently delete your account and all associated data.
|
||||
</span>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
</Card>
|
||||
|
@ -175,8 +199,9 @@ export default function SettingsPage() {
|
|||
<CardHeader>
|
||||
<CardTitle>Notification Preferences</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6'>
|
||||
<GroupWrapper>
|
||||
<CardContent className='space-y-6 my-2'>
|
||||
{/*-------------------- All --------------------*/}
|
||||
<GroupWrapper title='All'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<Label
|
||||
htmlFor='masterEmailNotifications'
|
||||
|
@ -187,7 +212,8 @@ export default function SettingsPage() {
|
|||
<Switch id='masterEmailNotifications' />
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
|
||||
{/*-------------------- All --------------------*/}
|
||||
{/*-------------------- Meetings --------------------*/}
|
||||
<GroupWrapper title='Meetings'>
|
||||
<div className='space-y-4'>
|
||||
<div className='flex items-center justify-between space-x-2'>
|
||||
|
@ -239,6 +265,8 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Meetings --------------------*/}
|
||||
{/*-------------------- Social --------------------*/}
|
||||
<GroupWrapper title='Social'>
|
||||
<div className='space-y-4'>
|
||||
<div className='flex items-center justify-between space-x-2'>
|
||||
|
@ -255,6 +283,7 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Social --------------------*/}
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
</Card>
|
||||
|
@ -267,8 +296,39 @@ export default function SettingsPage() {
|
|||
<CardHeader>
|
||||
<CardTitle>Calendar & Availability</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6'>
|
||||
{/*--------------------* Calendar --------------------*/}
|
||||
<CardContent className='space-y-6 my-2'>
|
||||
{/*-------------------- Date & Time Format --------------------*/}
|
||||
<GroupWrapper title='Date & Time Format'>
|
||||
<div className='flex flex-col space-y-4'>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor='dateFormat'>Date Format</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='dateFormat'>
|
||||
<SelectValue placeholder='Select date format' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='ddmmyyyy'>DD/MM/YYYY</SelectItem>
|
||||
<SelectItem value='mmddyyyy'>MM/DD/YYYY</SelectItem>
|
||||
<SelectItem value='yyyymmdd'>YYYY-MM-DD</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor='timeFormat'>Time Format</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='timeFormat'>
|
||||
<SelectValue placeholder='Select time format' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='24h'>24-hour</SelectItem>
|
||||
<SelectItem value='12h'>12-hour</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Date & Time Format --------------------*/}
|
||||
{/*-------------------- Calendar --------------------*/}
|
||||
<GroupWrapper title='Calendar'>
|
||||
<div className='space-y-4'>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
|
@ -306,9 +366,8 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*--------------------* Calendar --------------------*/}
|
||||
|
||||
{/*--------------------* Availability --------------------*/}
|
||||
{/*-------------------- Calendar --------------------*/}
|
||||
{/*-------------------- Availability --------------------*/}
|
||||
<GroupWrapper title='Availability'>
|
||||
<div className='space-y-4'>
|
||||
<div className='space-y-2'>
|
||||
|
@ -325,8 +384,9 @@ export default function SettingsPage() {
|
|||
<LabeledInput
|
||||
type='text'
|
||||
label='Minimum Notice for Bookings'
|
||||
icon={ClockAlert}
|
||||
subtext='Min time before a booking can be made.'
|
||||
placeholder='e.g., 1h'
|
||||
placeholder='e.g. 1h'
|
||||
defaultValue={''}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
|
@ -334,43 +394,65 @@ export default function SettingsPage() {
|
|||
<LabeledInput
|
||||
type='text'
|
||||
label='Booking Window (days in advance)'
|
||||
icon={ClockFading}
|
||||
subtext='Max time in advance a booking can be made.'
|
||||
placeholder='e.g., 30d'
|
||||
placeholder='e.g. 30d'
|
||||
defaultValue={''}
|
||||
></LabeledInput>
|
||||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*--------------------* Availability --------------------*/}
|
||||
|
||||
{/*--------------------* iCalendar Integration --------------------*/}
|
||||
<fieldset className='space-y-4 p-4 border rounded-md'>
|
||||
<legend className='text-sm font-medium px-1'>
|
||||
iCalendar Integration
|
||||
</legend>
|
||||
<div className='space-y-2'>
|
||||
<LabeledInput
|
||||
type='url'
|
||||
label='Import iCal Feed URL'
|
||||
subtext='Max time in advance a booking can be made.'
|
||||
placeholder='https://calendar.example.com/feed.ics'
|
||||
defaultValue={''}
|
||||
></LabeledInput>
|
||||
<Button size='sm' className='mt-1'>
|
||||
Add Feed
|
||||
</Button>
|
||||
{/*-------------------- Availability --------------------*/}
|
||||
{/*-------------------- iCalendar Integration --------------------*/}
|
||||
<GroupWrapper title='iCalendar Integration'>
|
||||
<div className='space-y-4'>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
className='space-y-2'
|
||||
>
|
||||
<LabeledInput
|
||||
type='url'
|
||||
label='Import iCal Feed URL'
|
||||
icon={CalendarCheck}
|
||||
placeholder='https://calendar.example.com/feed.ics'
|
||||
defaultValue={''}
|
||||
name='icalUrl'
|
||||
required
|
||||
></LabeledInput>
|
||||
<IconButton
|
||||
type='submit'
|
||||
size='sm'
|
||||
className='mt-1'
|
||||
variant={'secondary'}
|
||||
icon={CalendarPlus}
|
||||
title='Submit iCal URL'
|
||||
>
|
||||
Add Feed
|
||||
</IconButton>
|
||||
</form>
|
||||
<div className='space-y-2'>
|
||||
<Label>Export Your Calendar</Label>
|
||||
<IconButton
|
||||
variant='outline_muted'
|
||||
size='sm'
|
||||
icon={CalendarArrowUp}
|
||||
>
|
||||
Get iCal Export URL
|
||||
</IconButton>
|
||||
<IconButton
|
||||
variant='outline_muted'
|
||||
size='sm'
|
||||
className='ml-2'
|
||||
icon={CalendarArrowDown}
|
||||
>
|
||||
Download .ics File
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label>Export Your Calendar</Label>
|
||||
<Button variant='outline_muted' size='sm'>
|
||||
Get iCal Export URL
|
||||
</Button>
|
||||
<Button variant='outline_muted' size='sm' className='ml-2'>
|
||||
Download .ics File
|
||||
</Button>
|
||||
</div>
|
||||
</fieldset>
|
||||
{/*--------------------* iCalendar Integration --------------------*/}
|
||||
</GroupWrapper>
|
||||
{/*-------------------- iCalendar Integration --------------------*/}
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
</Card>
|
||||
|
@ -383,79 +465,94 @@ export default function SettingsPage() {
|
|||
<CardHeader>
|
||||
<CardTitle>Sharing & Privacy</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6'>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='defaultVisibility'>
|
||||
Default Calendar Visibility
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='defaultVisibility'>
|
||||
<SelectValue placeholder='Select visibility' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='private'>
|
||||
Private (Only You)
|
||||
</SelectItem>
|
||||
<SelectItem value='freebusy'>
|
||||
Free/Busy for Friends
|
||||
</SelectItem>
|
||||
<SelectItem value='fulldetails'>
|
||||
Full Details for Friends
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='whoCanSeeFull'>
|
||||
Who Can See Your Full Calendar Details?
|
||||
</Label>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
(Override for Default Visibility)
|
||||
<br />
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
This setting will override the default visibility for your
|
||||
calendar. You can set specific friends or groups to see
|
||||
your full calendar details.
|
||||
</span>
|
||||
</span>
|
||||
<Select>
|
||||
<SelectTrigger id='whoCanSeeFull'>
|
||||
<SelectValue placeholder='Select audience' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='me'>Only Me</SelectItem>
|
||||
<SelectItem value='friends'>My Friends</SelectItem>
|
||||
<SelectItem value='specific'>
|
||||
Specific Friends/Groups (manage separately)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='whoCanBook'>
|
||||
Who Can Book Time With You?
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='whoCanBook'>
|
||||
<SelectValue placeholder='Select audience' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='none'>No One</SelectItem>
|
||||
<SelectItem value='friends'>My Friends</SelectItem>
|
||||
<SelectItem value='specific'>
|
||||
Specific Friends/Groups (manage separately)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label>Blocked Users</Label>
|
||||
<Button variant='outline_muted'>Manage Blocked Users</Button>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Prevent specific users from seeing your calendar or booking
|
||||
time.
|
||||
</span>
|
||||
</div>
|
||||
<CardContent className='space-y-6 my-2'>
|
||||
{/*-------------------- Privacy Settigs --------------------*/}
|
||||
<GroupWrapper title='Privacy Settings'>
|
||||
<div className='flex flex-col space-y-4'>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor='defaultVisibility'>
|
||||
Default Calendar Visibility
|
||||
</Label>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Default setting for new friends.
|
||||
</span>
|
||||
<Select>
|
||||
<SelectTrigger id='defaultVisibility'>
|
||||
<SelectValue placeholder='Select visibility' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='private'>
|
||||
Private (Only You)
|
||||
</SelectItem>
|
||||
<SelectItem value='freebusy'>Free/Busy</SelectItem>
|
||||
<SelectItem value='fulldetails'>
|
||||
Full Details
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor='whoCanSeeFull'>
|
||||
Who Can See Your Full Calendar Details?
|
||||
</Label>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
(Override for Default Visibility)
|
||||
<br />
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
This setting will override the default visibility for
|
||||
your calendar. You can set specific friends or groups
|
||||
to see your full calendar details.
|
||||
</span>
|
||||
</span>
|
||||
<Select>
|
||||
<SelectTrigger id='whoCanSeeFull'>
|
||||
<SelectValue placeholder='Select audience' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='me'>Only Me</SelectItem>
|
||||
<SelectItem value='friends'>My Friends</SelectItem>
|
||||
<SelectItem value='specific'>
|
||||
Specific Friends/Groups (manage separately)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor='whoCanBook'>
|
||||
Who Can Book Time With You?
|
||||
</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='whoCanBook'>
|
||||
<SelectValue placeholder='Select audience' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='none'>No One</SelectItem>
|
||||
<SelectItem value='friends'>My Friends</SelectItem>
|
||||
<SelectItem value='specific'>
|
||||
Specific Friends/Groups (manage separately)
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='space-y-4'>
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label>Blocked Users</Label>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Prevent specific users from seeing your calendar or
|
||||
booking time.
|
||||
</span>
|
||||
<IconButton
|
||||
variant='outline_muted'
|
||||
size='sm'
|
||||
icon={UserLock}
|
||||
>
|
||||
Manage Blocked Users
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Privacy Settigs --------------------*/}
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
</Card>
|
||||
|
@ -468,36 +565,15 @@ export default function SettingsPage() {
|
|||
<CardHeader>
|
||||
<CardTitle>Appearance</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6'>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='theme'>Theme</Label>
|
||||
<ThemePicker />
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='dateFormat'>Date Format</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='dateFormat'>
|
||||
<SelectValue placeholder='Select date format' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='ddmmyyyy'>DD/MM/YYYY</SelectItem>
|
||||
<SelectItem value='mmddyyyy'>MM/DD/YYYY</SelectItem>
|
||||
<SelectItem value='yyyymmdd'>YYYY-MM-DD</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='timeFormat'>Time Format</Label>
|
||||
<Select>
|
||||
<SelectTrigger id='timeFormat'>
|
||||
<SelectValue placeholder='Select time format' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value='24h'>24-hour</SelectItem>
|
||||
<SelectItem value='12h'>12-hour</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<CardContent className='space-y-6 my-2'>
|
||||
{/*-------------------- Change Theme --------------------*/}
|
||||
<GroupWrapper title='Change Theme'>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='theme'>Theme</Label>
|
||||
<ThemePicker />
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
{/*-------------------- Change Theme --------------------*/}
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
</Card>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue