feat: tempcommit
This commit is contained in:
parent
f658a95b16
commit
a308158ca7
4 changed files with 102 additions and 66 deletions
|
@ -1,5 +1,9 @@
|
|||
import { Input, Textarea } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import React from 'react';
|
||||
import { Button } from '../ui/button';
|
||||
import { Eye, EyeOff } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
export default function LabeledInput({
|
||||
type,
|
||||
|
@ -12,7 +16,7 @@ export default function LabeledInput({
|
|||
error,
|
||||
...rest
|
||||
}: {
|
||||
type: 'text' | 'email' | 'password';
|
||||
type: 'text' | 'email' | 'password' | 'file';
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
|
@ -21,6 +25,8 @@ export default function LabeledInput({
|
|||
autocomplete?: string;
|
||||
error?: string;
|
||||
} & React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
const [passwordVisible, setPasswordVisible] = React.useState(false);
|
||||
|
||||
return (
|
||||
<div className='grid grid-cols-1 gap-1'>
|
||||
<Label htmlFor={name}>{label}</Label>
|
||||
|
@ -33,21 +39,36 @@ export default function LabeledInput({
|
|||
rows={3}
|
||||
/>
|
||||
) : (
|
||||
<span className='relative'>
|
||||
<Input
|
||||
type={type}
|
||||
className={cn(
|
||||
type === 'password' ? 'pr-[50px]' : '',
|
||||
variantSize === 'big'
|
||||
? 'h-12 file:h-10 text-lg gplaceholder:text-lg sm:text-2xl sm:placeholder:text-2xl'
|
||||
: '',
|
||||
)}
|
||||
type={passwordVisible ? 'text' : type}
|
||||
placeholder={placeholder}
|
||||
defaultValue={value}
|
||||
id={name}
|
||||
name={name}
|
||||
className={
|
||||
variantSize === 'big'
|
||||
? 'h-12 file:h-10 text-lg gplaceholder:text-lg sm:text-2xl sm:placeholder:text-2xl'
|
||||
: ''
|
||||
}
|
||||
autoComplete={autocomplete}
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
{type === 'password' && (
|
||||
<Button
|
||||
className='absolute right-0 top-0 w-[36px] h-[36px]'
|
||||
type='button'
|
||||
variant={'outline_muted'}
|
||||
onClick={() => setPasswordVisible((visible) => !visible)}
|
||||
>
|
||||
{passwordVisible ? <Eye /> : <EyeOff />}
|
||||
</Button>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{error && <p className='text-red-500 text-sm mt-1'>{error}</p>}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -45,13 +45,13 @@ const settingsSections: SettingsSection[] = [
|
|||
{
|
||||
label: 'Account',
|
||||
value: 'general',
|
||||
description: 'Manage your account details and preferences',
|
||||
description: 'Manage account details',
|
||||
icon: User,
|
||||
},
|
||||
{
|
||||
label: 'Notifications',
|
||||
value: 'notifications',
|
||||
description: 'Choose how you want to be notified',
|
||||
description: 'Choose notification Preferences',
|
||||
icon: Bell,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -27,6 +27,9 @@ import { useGetApiUserMe } from '@/generated/api/user/user';
|
|||
import { ThemePicker } from './theme-picker';
|
||||
import LabeledInput from '../custom-ui/labeled-input';
|
||||
import { GroupWrapper } from '../wrappers/group-wrapper';
|
||||
import { Avatar } from '../ui/avatar';
|
||||
import Image from 'next/image';
|
||||
import { User } from 'lucide-react';
|
||||
|
||||
export default function SettingsPage() {
|
||||
const router = useRouter();
|
||||
|
@ -43,51 +46,50 @@ export default function SettingsPage() {
|
|||
<CardTitle>Account Settings</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='space-y-6 mt-2'>
|
||||
<GroupWrapper legend='General Settings'>
|
||||
<GroupWrapper title='General Settings'>
|
||||
<div className='space-y-4'>
|
||||
<div className='flex items-center justify-evenly'>
|
||||
<div>
|
||||
<Label htmlFor='displayName'>First Name</Label>
|
||||
<Input
|
||||
id='displayName'
|
||||
placeholder='Your Name'
|
||||
<LabeledInput
|
||||
label='First Name'
|
||||
type='text'
|
||||
placeholder='First Name'
|
||||
defaultValue={data?.data.user.first_name ?? ''}
|
||||
/>
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor='displayName'>Last Name</Label>
|
||||
<Input
|
||||
id='displayName'
|
||||
placeholder='Your Name'
|
||||
<LabeledInput
|
||||
label='Last Name'
|
||||
type='text'
|
||||
placeholder='Last Name'
|
||||
defaultValue={data?.data.user.last_name ?? ''}
|
||||
/>
|
||||
></LabeledInput>
|
||||
</div>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='displayName'>Display Name</Label>
|
||||
<Input
|
||||
id='displayName'
|
||||
placeholder='Your Name'
|
||||
<LabeledInput
|
||||
label='Display Name'
|
||||
type='text'
|
||||
placeholder='Display Name'
|
||||
defaultValue={data?.data.user.name}
|
||||
/>
|
||||
></LabeledInput>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='email'>Email Address</Label>
|
||||
<Input
|
||||
id='email'
|
||||
<div className='space-y-2 space-b-2'>
|
||||
<LabeledInput
|
||||
type='email'
|
||||
placeholder='your.email@example.com'
|
||||
readOnly
|
||||
defaultValue={data?.data.user.email}
|
||||
/>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
label='Email Address'
|
||||
placeholder='Your E-Mail'
|
||||
defaultValue={data?.data.user.email ?? ''}
|
||||
></LabeledInput>
|
||||
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Email might be managed by your SSO provider.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
<GroupWrapper legend='Reset Password'>
|
||||
<div className='flex items-center justify-evenly'>
|
||||
<GroupWrapper title='Reset Password'>
|
||||
<div className='flex items-center justify-evenly sm:flex-row flex-col gap-6'>
|
||||
<div>
|
||||
<LabeledInput
|
||||
type='password'
|
||||
|
@ -114,12 +116,25 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
</div>
|
||||
</GroupWrapper>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='profilePicture'>Profile Picture</Label>
|
||||
<Input id='profilePicture' type='file' />
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
Upload a new profile picture.
|
||||
</p>
|
||||
<div className='space-y-2 grid grid-cols-[1fr_auto] gap-4'>
|
||||
<LabeledInput
|
||||
label='Profile Picture'
|
||||
type='file'
|
||||
placeholder='Upload Profile Picture'
|
||||
defaultValue={data?.data.user.image ?? ''}
|
||||
></LabeledInput>
|
||||
<Avatar className='flex justify-center items-center'>
|
||||
{data?.data.user.image ? (
|
||||
<Image
|
||||
src={data?.data.user.image}
|
||||
alt='Avatar'
|
||||
width='20'
|
||||
height='20'
|
||||
/>
|
||||
) : (
|
||||
<User />
|
||||
)}
|
||||
</Avatar>
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<Label htmlFor='timezone'>Timezone</Label>
|
||||
|
@ -143,9 +158,9 @@ export default function SettingsPage() {
|
|||
</div>
|
||||
<div className='pt-4'>
|
||||
<Button variant='secondary'>Delete Account</Button>
|
||||
<p className='text-sm text-muted-foreground pt-1'>
|
||||
<span className='text-sm text-muted-foreground pt-1'>
|
||||
Permanently delete your account and all associated data.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
|
@ -277,10 +292,10 @@ export default function SettingsPage() {
|
|||
</legend>
|
||||
<div className='space-y-2'>
|
||||
<Label>Working Hours</Label>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Define your typical available hours (e.g., Monday-Friday,
|
||||
9 AM - 5 PM).
|
||||
</p>
|
||||
</span>
|
||||
<Button variant='outline_muted' size='sm'>
|
||||
Set Working Hours
|
||||
</Button>
|
||||
|
@ -289,9 +304,9 @@ export default function SettingsPage() {
|
|||
<Label htmlFor='minNoticeBooking'>
|
||||
Minimum Notice for Bookings
|
||||
</Label>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Min time before a booking can be made.
|
||||
</p>
|
||||
</span>
|
||||
<div className='space-y-2'>
|
||||
<Input
|
||||
id='bookingWindow'
|
||||
|
@ -304,9 +319,9 @@ export default function SettingsPage() {
|
|||
<Label htmlFor='bookingWindow'>
|
||||
Booking Window (days in advance)
|
||||
</Label>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Max time in advance a booking can be made.
|
||||
</p>
|
||||
</span>
|
||||
<Input
|
||||
id='bookingWindow'
|
||||
type='number'
|
||||
|
@ -378,7 +393,7 @@ export default function SettingsPage() {
|
|||
<Label htmlFor='whoCanSeeFull'>
|
||||
Who Can See Your Full Calendar Details?
|
||||
</Label>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
(Override for Default Visibility)
|
||||
<br />
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
|
@ -386,7 +401,7 @@ export default function SettingsPage() {
|
|||
calendar. You can set specific friends or groups to see
|
||||
your full calendar details.
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<Select>
|
||||
<SelectTrigger id='whoCanSeeFull'>
|
||||
<SelectValue placeholder='Select audience' />
|
||||
|
@ -420,10 +435,10 @@ export default function SettingsPage() {
|
|||
<div className='space-y-2'>
|
||||
<Label>Blocked Users</Label>
|
||||
<Button variant='outline_muted'>Manage Blocked Users</Button>
|
||||
<p className='text-sm text-muted-foreground'>
|
||||
<span className='text-sm text-muted-foreground'>
|
||||
Prevent specific users from seeing your calendar or booking
|
||||
time.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</ScrollableSettingsWrapper>
|
||||
|
|
|
@ -3,20 +3,20 @@ import type * as React from 'react';
|
|||
|
||||
interface ScrollableSettingsWrapperProps {
|
||||
className?: string;
|
||||
legend?: string;
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function GroupWrapper({
|
||||
className,
|
||||
legend,
|
||||
title,
|
||||
children,
|
||||
}: ScrollableSettingsWrapperProps) {
|
||||
return (
|
||||
<fieldset
|
||||
className={cn('space-t-4 p-4 border rounded-md shadow-md', className)}
|
||||
>
|
||||
<legend className='text-sm font-medium px-1'>{legend}</legend>
|
||||
<legend className='text-sm font-medium px-1'>{title}</legend>
|
||||
{children}
|
||||
</fieldset>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue