Skip to content

Commit e47aac6

Browse files
committed
feat(ui): mobile-responsive notification admin page
1 parent 11f3a9a commit e47aac6

12 files changed

Lines changed: 82 additions & 63 deletions

File tree

ui/dashboard/src/components/navigation/index.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,19 @@ const Navigation = ({
311311

312312
<div
313313
className={cn(
314-
'flex gap-5 items-center justify-between',
315-
isExpanded ? 'flex-row' : 'flex-col md:flex-row'
314+
'flex items-center justify-between',
315+
isExpanded
316+
? 'flex-row gap-5'
317+
: 'flex-col gap-3 md:flex-row md:gap-5'
316318
)}
317319
>
318320
<UserMenu onOpenSwitchOrg={onOpenSwitchOrg} />
319-
<div className="flex items-center justify-center gap-2">
321+
<div
322+
className={cn(
323+
'flex items-center justify-center',
324+
isExpanded ? 'gap-2' : 'flex-col gap-3 md:flex-row md:gap-2'
325+
)}
326+
>
320327
<NotificationBell envUrlCode={envUrlCode} />
321328
<button
322329
type="button"

ui/dashboard/src/components/navigation/notification-bell.tsx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const NotificationBell = ({ envUrlCode }: { envUrlCode: string }) => {
8989
align="start"
9090
side="top"
9191
sideOffset={8}
92-
className="w-[380px] rounded-lg border-none bg-white p-0 shadow-menu"
92+
className="w-[calc(100vw-2rem)] max-w-[380px] rounded-lg border-none bg-white p-0 shadow-menu"
9393
>
9494
<div className="flex items-center justify-between px-4 py-3.5">
9595
<span className="typo-head-bold-medium text-gray-900">
@@ -121,24 +121,26 @@ const NotificationBell = ({ envUrlCode }: { envUrlCode: string }) => {
121121
onClick={() => onSelectNotification(notification)}
122122
className="flex w-full flex-col items-start gap-1.5 border-t border-gray-100 px-4 py-3.5 text-left first:border-t-0 hover:bg-gray-50"
123123
>
124-
<div className="flex w-full items-center gap-2">
125-
{!notification.read && (
126-
<span className="mt-1.5 size-1.5 shrink-0 rounded-full bg-primary-500" />
127-
)}
128-
<span
129-
className={cn(
130-
'typo-para-medium text-gray-900 truncate',
131-
!notification.read ? 'font-semibold' : 'ml-3.5'
124+
<div className="flex w-full flex-wrap items-center gap-x-2 gap-y-1">
125+
<div className="flex min-w-0 flex-1 items-center gap-2">
126+
{!notification.read && (
127+
<span className="size-1.5 shrink-0 rounded-full bg-primary-500" />
132128
)}
133-
>
134-
{notification.title}
129+
<span
130+
className={cn(
131+
'typo-para-medium text-gray-900 truncate',
132+
!notification.read ? 'font-semibold' : 'ml-3.5'
133+
)}
134+
>
135+
{notification.title}
136+
</span>
137+
</div>
138+
<span className="ml-auto shrink-0 typo-para-tiny text-gray-500">
139+
{formatDateTime(notification.publishedAt)}
135140
</span>
136141
{notification.tags[0] && (
137142
<TagChip tag={notification.tags[0]} hideDot />
138143
)}
139-
<span className="ml-auto shrink-0 typo-para-tiny text-gray-500">
140-
{formatDateTime(notification.publishedAt)}
141-
</span>
142144
</div>
143145
<span
144146
className={cn(

ui/dashboard/src/components/pagination/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ const Pagination = ({
3232
const endItem = Math.min(cursor + pageSize, totalCount);
3333

3434
return (
35-
<div className={cn('flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2 mt-4 sm:mt-0', className)}>
35+
<div
36+
className={cn(
37+
'flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2 mt-4 sm:mt-0',
38+
className
39+
)}
40+
>
3641
{totalCount > 0 && (
3742
<PaginationCount
3843
totalItems={totalCount}

ui/dashboard/src/pages/feature-flag-details/variation/variations-section/variations.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ const Variations = ({
358358
isBoolean || isRunningExperiment || !editable
359359
}
360360
placeholder={t('form:feature-flags.value')}
361-
className="px-3 min-w-[300px]"
361+
className="px-3 min-w-[300px]"
362362
/>
363363
)}
364364
</Form.Control>

ui/dashboard/src/pages/notification-feed/drafts/draft-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const DraftCard = ({ draft, active, onClick, onDelete }: DraftCardProps) => {
3434
{draft.title}
3535
</span>
3636
{draft.content && (
37-
<p className="line-clamp-2 typo-para-small text-gray-500">
37+
<p className="line-clamp-2 break-words typo-para-small text-gray-500">
3838
{markdownToText(draft.content)}
3939
</p>
4040
)}

ui/dashboard/src/pages/notification-feed/elements/notification-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const NotificationCard = ({
2424
variant="text"
2525
onClick={onClick}
2626
className={cn(
27-
'flex h-full w-full flex-col items-start justify-start gap-2 whitespace-normal text-left transition-colors',
27+
'flex h-full max-h-none w-full flex-col items-start justify-start gap-2 whitespace-normal text-left transition-colors',
2828
bordered
2929
? cn(
3030
'rounded-lg border p-4',

ui/dashboard/src/pages/notification-feed/elements/notification-detail.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ const PersonBadge = ({ email }: { email: string }) => {
3434
const initial = (email.trim()[0] ?? '?').toUpperCase();
3535
const name = email.split('@')[0];
3636
return (
37-
<div className="flex items-center gap-2">
38-
<span className="typo-para-small text-gray-900">{name}</span>
39-
<span className="flex-center size-6 rounded-full bg-primary-100 typo-para-tiny font-medium text-primary-600">
37+
<div className="flex min-w-0 items-center gap-2">
38+
<span className="truncate typo-para-small text-gray-900">{name}</span>
39+
<span className="flex-center shrink-0 size-6 rounded-full bg-primary-100 typo-para-tiny font-medium text-primary-600">
4040
{initial}
4141
</span>
4242
</div>
@@ -50,9 +50,9 @@ const DetailRow = ({
5050
label: string;
5151
children: ReactNode;
5252
}) => (
53-
<div className="flex min-h-8 items-center justify-between gap-4">
54-
<span className="typo-para-small text-gray-500">{label}</span>
55-
<div className="typo-para-small text-gray-900">{children}</div>
53+
<div className="flex min-h-8 flex-wrap items-center justify-between gap-x-4 gap-y-1">
54+
<span className="shrink-0 typo-para-small text-gray-500">{label}</span>
55+
<div className="min-w-0 typo-para-small text-gray-900">{children}</div>
5656
</div>
5757
);
5858

@@ -161,7 +161,7 @@ const NotificationDetailModal = ({
161161
onClose={onClose}
162162
>
163163
<div className="w-full h-full flex flex-col">
164-
<div className="flex flex-1 flex-col gap-6 overflow-auto p-6">
164+
<div className="flex flex-1 flex-col gap-6 overflow-auto p-4 sm:p-6">
165165
{localizations.length > 1 && (
166166
<LanguageTabs
167167
fields={localizations.map(l => ({
@@ -225,7 +225,7 @@ const NotificationDetailModal = ({
225225
</Section>
226226
</div>
227227

228-
<div className="flex items-center justify-end gap-3 border-t border-gray-200 px-6 py-4">
228+
<div className="flex flex-wrap items-center justify-end gap-3 border-t border-gray-200 px-4 py-4 sm:px-6">
229229
<Button variant="secondary" onClick={onClose}>
230230
{t('close')}
231231
</Button>

ui/dashboard/src/pages/notification-feed/feed/notification-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ const NotificationList = ({
118118
</div>
119119

120120
{!read && selected.size > 0 && (
121-
<div className="flex items-center justify-between rounded-lg border border-gray-200 bg-gray-50 px-4 py-3">
121+
<div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3">
122122
<div className="flex items-center gap-3">
123123
<span className="typo-para-medium text-gray-700">
124124
{t('selected', { count: selected.size })}

ui/dashboard/src/pages/notification-feed/feed/notification-row.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,45 @@ const NotificationRow = ({
3232
/>
3333
</div>
3434
)}
35-
<div className="flex-1">
35+
<div className="flex-1 w-full">
3636
<NotificationCard
3737
onClick={onClick}
3838
bordered={false}
3939
header={
4040
<div className="flex w-full flex-col gap-1">
41-
<div className="flex w-full items-center gap-2">
41+
<div className="flex w-full min-w-0 items-center gap-2">
4242
{!notification.read && (
4343
<span className="size-2 shrink-0 rounded-full bg-primary-500" />
4444
)}
4545
<span
4646
className={cn(
47-
'truncate typo-para-medium text-gray-900',
47+
'min-w-0 flex-1 truncate typo-para-medium text-gray-900',
4848
!notification.read && 'font-semibold'
4949
)}
5050
>
5151
{notification.title}
5252
</span>
53-
<TagList tags={notification.tags} />
54-
<span className="ml-auto shrink-0 typo-para-tiny text-gray-500">
55-
{formatDateTime(notification.publishedAt)}
56-
</span>
5753
</div>
5854
{notification.content && (
59-
<p className="line-clamp-2 typo-para-small text-gray-500">
55+
<p className="line-clamp-2 break-words typo-para-small text-gray-500">
6056
{markdownToText(notification.content)}
6157
</p>
6258
)}
6359
</div>
6460
}
6561
footer={
66-
<span className="typo-para-small text-gray-500">
67-
{notification.createdBy.split('@')[0]}
68-
</span>
62+
<div className="flex w-full items-center justify-between">
63+
<span className="typo-para-small text-gray-500">
64+
{notification.createdBy.split('@')[0]}
65+
</span>
66+
<span className="typo-para-tiny text-gray-500">
67+
{formatDateTime(notification.publishedAt)}
68+
</span>
69+
</div>
6970
}
70-
/>
71+
>
72+
<TagList tags={notification.tags} />
73+
</NotificationCard>
7174
</div>
7275
</div>
7376
);

ui/dashboard/src/pages/notification-feed/page-content.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ const PageContent = ({
123123
action={
124124
<>
125125
<Dropdown
126-
className="w-[200px]"
127-
wrapTriggerStyle="w-fit"
126+
className="w-full sm:w-[200px]"
127+
wrapTriggerStyle="w-full sm:w-fit"
128128
isTruncate={false}
129129
value={filters.sort}
130130
options={notificationSortOptions}
@@ -151,29 +151,31 @@ const PageContent = ({
151151
className="flex flex-1 flex-col"
152152
>
153153
<div
154-
className={cn('p-6 grid grid-cols-1 gap-8', {
154+
className={cn('p-3 sm:p-6 grid grid-cols-1 gap-8', {
155155
'lg:grid-cols-[1fr_360px]': filters.tab === 'publish'
156156
})}
157157
>
158-
<div className="flex flex-col relative">
159-
<div className="flex items-center justify-between">
160-
<TabsList className="justify-start">
161-
<TabsTrigger value="unread">
162-
{t('unread')} ({unreadCount})
163-
</TabsTrigger>
164-
<TabsTrigger value="read">{t('read')}</TabsTrigger>
165-
{isSystemAdmin && (
166-
<TabsTrigger value="publish">
167-
{t('publish-notification')}
158+
<div className="flex flex-col gap-3">
159+
<div className="flex flex-wrap items-center justify-between gap-3">
160+
<div className="w-auto min-w-0 flex-1 overflow-x-auto">
161+
<TabsList className="w-max justify-start sm:w-auto">
162+
<TabsTrigger value="unread">
163+
{t('unread')} ({unreadCount})
168164
</TabsTrigger>
169-
)}
170-
</TabsList>
165+
<TabsTrigger value="read">{t('read')}</TabsTrigger>
166+
{isSystemAdmin && (
167+
<TabsTrigger value="publish">
168+
{t('publish-notification')}
169+
</TabsTrigger>
170+
)}
171+
</TabsList>
172+
</div>
171173

172174
{filters.tab === 'unread' && (
173175
<Button
174176
variant="text"
175177
size="sm"
176-
className="absolute right-0 top-0"
178+
className="shrink-0"
177179
onClick={() => markAllAsRead.mutate()}
178180
disabled={unreadCount === 0 || markAllAsRead.isPending}
179181
>
@@ -215,7 +217,7 @@ const PageContent = ({
215217
</div>
216218

217219
{isSystemAdmin && filters.tab === 'publish' && (
218-
<aside className="lg:border-l lg:border-gray-200 lg:pl-8">
220+
<aside className="border-t border-gray-200 pt-8 lg:border-l lg:border-t-0 lg:pl-8 lg:pt-0">
219221
<DraftsPanel
220222
filters={filters}
221223
onSelect={onSelectDetail}

0 commit comments

Comments
 (0)