Skip to content

Commit 6fd609a

Browse files
authored
fix: personal setting modal style (#2233)
* fix: personal setting modal style * fix more style and i18n issues * Remove unused comment in LanguagePicker component Remove commented code about language selection fallback. Signed-off-by: Jun Lu <[email protected]> --------- Signed-off-by: Jun Lu <[email protected]>
1 parent b4cb680 commit 6fd609a

File tree

28 files changed

+417
-352
lines changed

28 files changed

+417
-352
lines changed
18.4 KB
Loading
18.7 KB
Loading
3.04 KB
Loading
2.8 KB
Loading
3.07 KB
Loading

apps/nextjs-app/src/features/app/components/LanguagePicker.tsx

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { useMutation } from '@tanstack/react-query';
22
import { updateUserLang } from '@teable/openapi';
3-
import { Button } from '@teable/ui-lib/shadcn/ui/button';
43
import {
5-
DropdownMenu,
6-
DropdownMenuContent,
7-
DropdownMenuRadioGroup,
8-
DropdownMenuRadioItem,
9-
DropdownMenuTrigger,
10-
} from '@teable/ui-lib/shadcn/ui/dropdown-menu';
4+
Select,
5+
SelectContent,
6+
SelectItem,
7+
SelectTrigger,
8+
SelectValue,
9+
} from '@teable/ui-lib/shadcn/ui/select';
1110
import { toast } from '@teable/ui-lib/shadcn/ui/sonner';
1211
import { useTranslation } from 'next-i18next';
1312

@@ -52,33 +51,22 @@ export const LanguagePicker: React.FC<{ className?: string }> = ({ className })
5251
};
5352

5453
const currentLanguage = i18n.language.split('-')[0];
54+
const selectedValue = languages.some((l) => l.key === currentLanguage)
55+
? currentLanguage
56+
: 'default';
57+
5558
return (
56-
<DropdownMenu>
57-
<DropdownMenuTrigger asChild>
58-
<Button className={className} variant="outline">
59-
{languages.find((item) => item.key == currentLanguage)?.title || 'default'}
60-
</Button>
61-
</DropdownMenuTrigger>
62-
<DropdownMenuContent className="w-56">
63-
<DropdownMenuRadioGroup
64-
value={currentLanguage}
65-
onValueChange={(value) => {
66-
setLanguage(value);
67-
}}
68-
>
69-
{languages.map((item) => {
70-
return (
71-
<DropdownMenuRadioItem
72-
key={item.key}
73-
disabled={currentLanguage === item.key}
74-
value={item.key}
75-
>
76-
{item.title}
77-
</DropdownMenuRadioItem>
78-
);
79-
})}
80-
</DropdownMenuRadioGroup>
81-
</DropdownMenuContent>
82-
</DropdownMenu>
59+
<Select value={selectedValue} onValueChange={setLanguage}>
60+
<SelectTrigger className={`w-full max-w-[320px] ${className || ''}`}>
61+
<SelectValue placeholder="Select Language" />
62+
</SelectTrigger>
63+
<SelectContent>
64+
{languages.map((item) => (
65+
<SelectItem key={item.key} value={item.key}>
66+
{item.title}
67+
</SelectItem>
68+
))}
69+
</SelectContent>
70+
</Select>
8371
);
8472
};

apps/nextjs-app/src/features/app/components/SideBarFooter.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@ export const SideBarFooter: React.FC = () => {
1313
const { user } = useSession();
1414

1515
return (
16-
<div className="m-2 flex flex-col items-center gap-1">
17-
<div className="flex w-full justify-between">
16+
<div className="m-2 flex flex-col items-center gap-2">
17+
<div className="flex w-full justify-between gap-2">
1818
<UserNav>
19-
<Button variant="ghost" size={'xs'} className="w-full justify-start text-sm font-normal">
20-
<UserAvatar user={user} />
19+
<Button
20+
variant="ghost"
21+
size={'sm'}
22+
className="w-full justify-start py-1.5 pl-2 text-sm font-normal"
23+
>
24+
<UserAvatar className="border" user={user} />
2125
{user.name}
2226
</Button>
2327
</UserNav>

apps/nextjs-app/src/features/app/components/notifications/NotificationsManage.tsx

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export const NotificationsManage: React.FC = () => {
124124
<Button
125125
variant="ghost"
126126
size={'xs'}
127-
className="relative"
127+
className="relative "
128128
onClick={() => {
129129
setNotifyStatus(NotificationStatesEnum.Unread);
130130
refresh();
@@ -142,6 +142,32 @@ export const NotificationsManage: React.FC = () => {
142142
</PopoverTrigger>
143143
<PopoverContent side="left" align="end" className="min-w-[500px] p-0">
144144
<div className="w-full">
145+
<div className="flex items-center justify-between border-b border-border-high p-4">
146+
<div className="text-base font-semibold">{t('notification.title')}</div>
147+
{renderNewButton()}
148+
<div>
149+
<Button
150+
variant="ghost"
151+
size="xs"
152+
className={cn('ml-2', {
153+
'bg-accent': notifyStatus === NotificationStatesEnum.Unread,
154+
})}
155+
onClick={() => setNotifyStatus(NotificationStatesEnum.Unread)}
156+
>
157+
{t('notification.title')}
158+
</Button>
159+
<Button
160+
variant="ghost"
161+
size="xs"
162+
className={cn('ml-2', {
163+
'bg-accent': notifyStatus === NotificationStatesEnum.Read,
164+
})}
165+
onClick={() => setNotifyStatus(NotificationStatesEnum.Read)}
166+
>
167+
{t('notification.read')}
168+
</Button>
169+
</div>
170+
</div>
145171
<NotificationList
146172
className="relative max-h-[78vh] overflow-auto"
147173
notifyStatus={notifyStatus}
@@ -168,32 +194,6 @@ export const NotificationsManage: React.FC = () => {
168194
) : (
169195
''
170196
)}
171-
<div className="flex items-center justify-between border-t border-border-high p-4">
172-
<div className="text-sm font-normal">{t('notification.title')}</div>
173-
{renderNewButton()}
174-
<div>
175-
<Button
176-
variant="ghost"
177-
size="xs"
178-
className={cn('ml-2', {
179-
'bg-surface border': notifyStatus === NotificationStatesEnum.Unread,
180-
})}
181-
onClick={() => setNotifyStatus(NotificationStatesEnum.Unread)}
182-
>
183-
{t('notification.title')}
184-
</Button>
185-
<Button
186-
variant="ghost"
187-
size="xs"
188-
className={cn('ml-2', {
189-
'bg-surface border': notifyStatus === NotificationStatesEnum.Read,
190-
})}
191-
onClick={() => setNotifyStatus(NotificationStatesEnum.Read)}
192-
>
193-
{t('notification.read')}
194-
</Button>
195-
</div>
196-
</div>
197197
</div>
198198
</PopoverContent>
199199
</Popover>

apps/nextjs-app/src/features/app/components/setting/Account.tsx

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
Button,
66
Input,
77
Label,
8-
Separator,
98
Tooltip,
109
TooltipContent,
1110
TooltipProvider,
@@ -56,7 +55,7 @@ export const Account: React.FC = () => {
5655

5756
const avatarComponent = (
5857
<div className="group relative flex h-fit items-center justify-center">
59-
<UserAvatar className="size-14" width={80} height={80} user={sessionUser} />
58+
<UserAvatar className="size-14 border" width={80} height={80} user={sessionUser} />
6059
<div className="absolute left-0 top-0 size-full rounded-full bg-transparent group-hover:bg-muted-foreground/20">
6160
<input
6261
type="file"
@@ -69,71 +68,75 @@ export const Account: React.FC = () => {
6968
);
7069

7170
return (
72-
<div className="space-y-6">
71+
<div className="flex h-full flex-col gap-6 border-l px-8 py-4">
7372
<h3 className="text-lg font-medium">{t('settings.account.title')}</h3>
74-
<Separator />
75-
<div className="flex">
76-
{isTouchDevice ? (
77-
avatarComponent
78-
) : (
79-
<TooltipProvider>
80-
<Tooltip>
81-
<TooltipTrigger asChild>{avatarComponent}</TooltipTrigger>
82-
<TooltipContent>
83-
<p>{t('settings.account.updatePhoto')}</p>
84-
</TooltipContent>
85-
</Tooltip>
86-
</TooltipProvider>
87-
)}
88-
89-
<div className="ml-4 flex-1 pt-3">
90-
<Input
91-
className="w-full"
92-
defaultValue={sessionUser.name}
93-
onBlur={(e) => toggleRenameUser(e)}
94-
/>
95-
<Label className="text-xs text-muted-foreground" htmlFor="Preferred name">
96-
{t('settings.account.updateNameDesc')}
97-
</Label>
98-
</div>
99-
</div>
100-
<div>
101-
<h3 className="text-base font-medium">
102-
{t('settings.account.securityTitle')}
103-
{!sessionUser.hasPassword && <AddPassword />}
104-
</h3>
105-
<Separator className="my-2" />
106-
<div className="space-y-4">
107-
<div className="flex items-center justify-between">
108-
<div>
109-
<Label>{t('settings.account.email')}</Label>
110-
<div className="text-xs text-muted-foreground">{sessionUser.email}</div>
111-
</div>
112-
<ChangeEmailDialog>
113-
<Button className="float-right" size={'sm'} variant={'outline'}>
114-
{t('settings.account.changeEmail.title')}
115-
</Button>
116-
</ChangeEmailDialog>
73+
<div className="flex flex-1 flex-col gap-6">
74+
<div className="flex flex-col items-start justify-start">
75+
{isTouchDevice ? (
76+
avatarComponent
77+
) : (
78+
<TooltipProvider>
79+
<Tooltip>
80+
<TooltipTrigger asChild>{avatarComponent}</TooltipTrigger>
81+
<TooltipContent>
82+
<p>{t('settings.account.updatePhoto')}</p>
83+
</TooltipContent>
84+
</Tooltip>
85+
</TooltipProvider>
86+
)}
87+
<div className="flex-1 pt-4">
88+
<Input
89+
className="max-w-[320px]"
90+
defaultValue={sessionUser.name}
91+
onBlur={(e) => toggleRenameUser(e)}
92+
/>
93+
<Label className="text-xs font-normal text-muted-foreground" htmlFor="Preferred name">
94+
{t('settings.account.updateNameDesc')}
95+
</Label>
11796
</div>
118-
{sessionUser.hasPassword && (
119-
<div className="flex items-center justify-between">
120-
<div>
121-
<Label>{t('settings.account.password')}</Label>
122-
<div className="text-xs text-muted-foreground">
123-
{t('settings.account.passwordDesc')}
124-
</div>
97+
</div>
98+
<div>
99+
<h3 className="mb-3 text-sm font-medium">
100+
{t('settings.account.securityTitle')}
101+
{!sessionUser.hasPassword && <AddPassword />}
102+
</h3>
103+
<div className="space-y-3">
104+
<div className="flex items-center justify-between rounded-md border bg-card px-4 py-3">
105+
<div className="flex flex-col gap-1">
106+
<p className="text-sm font-medium">{t('settings.account.email')}</p>
107+
<div className="text-xs text-muted-foreground">{sessionUser.email}</div>
125108
</div>
126-
<ChangePasswordDialog>
109+
<ChangeEmailDialog>
127110
<Button className="float-right" size={'sm'} variant={'outline'}>
128-
{t('settings.account.changePassword.title')}
111+
{t('settings.account.changeEmail.title')}
129112
</Button>
130-
</ChangePasswordDialog>
113+
</ChangeEmailDialog>
131114
</div>
132-
)}
133-
115+
{sessionUser.hasPassword && (
116+
<div className="flex items-center justify-between rounded-md border bg-card px-4 py-3">
117+
<div className="flex flex-col gap-1">
118+
<p className="text-sm font-medium">{t('settings.account.password')}</p>
119+
<div className="text-xs text-muted-foreground">
120+
{t('settings.account.passwordDesc')}
121+
</div>
122+
</div>
123+
<ChangePasswordDialog>
124+
<Button className="float-right" size={'sm'} variant={'outline'}>
125+
{t('settings.account.changePassword.title')}
126+
</Button>
127+
</ChangePasswordDialog>
128+
</div>
129+
)}
130+
</div>
131+
</div>
132+
<div>
133+
{' '}
134134
<DeleteAccountDialog />
135135
</div>
136136
</div>
137+
<div className="flex w-full items-center justify-center pt-4 text-xs text-muted-foreground">
138+
{`${t('settings.setting.version')}: ${process.env.NEXT_PUBLIC_BUILD_VERSION}`}
139+
</div>
137140
</div>
138141
);
139142
};

apps/nextjs-app/src/features/app/components/setting/Notifications.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ export const Notifications: React.FC = () => {
1111
};
1212

1313
return (
14-
<div className="space-y-6">
15-
<div>
16-
<h3 className="text-lg font-medium">{t('settings.notify.title')}</h3>
17-
</div>
18-
<Separator />
19-
<div className="flex items-center justify-start">
20-
<div className="mr-[10%]">
21-
<Label>{t('settings.notify.label')}</Label>
22-
<div className="text-sm text-muted-foreground">{t('settings.notify.desc')}</div>
14+
<div className="flex h-full flex-col gap-6 border-l px-8 py-4">
15+
<h3 className="text-lg font-medium">{t('settings.notify.title')}</h3>
16+
<div className="flex items-center justify-between gap-4 rounded-md border bg-card px-4 py-3">
17+
<div className="flex flex-col gap-1">
18+
<p className="text-sm font-medium">{t('settings.notify.label')}</p>
19+
<p className="text-xs text-muted-foreground">{t('settings.notify.desc')}</p>
2320
</div>
2421
<Switch
2522
id="notify-meta-email"

0 commit comments

Comments
 (0)