@hed-hog/core 0.0.278 → 0.0.285
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/dist/auth/auth.controller.d.ts +3 -3
- package/dist/auth/auth.service.d.ts +8 -8
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +12 -0
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js +9 -0
- package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +12 -0
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.js +25 -0
- package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
- package/dist/file/file.controller.d.ts +2 -2
- package/dist/file/file.service.d.ts +4 -4
- package/dist/role/guards/role.guard.d.ts.map +1 -1
- package/dist/role/guards/role.guard.js +1 -1
- package/dist/role/guards/role.guard.js.map +1 -1
- package/dist/session/session.controller.d.ts +1 -1
- package/dist/session/session.service.d.ts +3 -3
- package/dist/user/user.controller.d.ts +2 -2
- package/dist/user/user.service.d.ts +6 -6
- package/hedhog/data/dashboard_component.yaml +95 -77
- package/hedhog/data/dashboard_component_role.yaml +91 -79
- package/hedhog/data/dashboard_item.yaml +121 -101
- package/hedhog/data/route.yaml +8 -0
- package/hedhog/frontend/app/ai_agent/page.tsx.ejs +69 -62
- package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +23 -12
- package/hedhog/frontend/app/dashboard/components/draggable-grid.tsx.ejs +80 -5
- package/hedhog/frontend/app/dashboard/components/widgets/account-security.tsx.ejs +33 -29
- package/hedhog/frontend/app/dashboard/components/widgets/activity-timeline.tsx.ejs +18 -14
- package/hedhog/frontend/app/dashboard/components/widgets/email-notifications.tsx.ejs +39 -32
- package/hedhog/frontend/app/dashboard/components/widgets/login-history-chart.tsx.ejs +22 -19
- package/hedhog/frontend/app/dashboard/components/widgets/menus-card.tsx.ejs +58 -0
- package/hedhog/frontend/app/dashboard/components/widgets/routes-card.tsx.ejs +58 -0
- package/hedhog/frontend/app/dashboard/components/widgets/stat-access-level.tsx.ejs +18 -18
- package/hedhog/frontend/app/dashboard/components/widgets/stat-actions-today.tsx.ejs +18 -18
- package/hedhog/frontend/app/dashboard/components/widgets/stat-consecutive-days.tsx.ejs +18 -18
- package/hedhog/frontend/app/dashboard/components/widgets/stat-online-time.tsx.ejs +18 -18
- package/hedhog/frontend/app/dashboard/components/widgets/user-roles.tsx.ejs +15 -11
- package/hedhog/frontend/app/dashboard/components/widgets/user-sessions.tsx.ejs +39 -37
- package/hedhog/frontend/app/dashboard/dashboard.css.ejs +20 -4
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +36 -47
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +176 -126
- package/hedhog/frontend/app/menu/page.tsx.ejs +45 -39
- package/hedhog/frontend/app/roles/page.tsx.ejs +45 -46
- package/hedhog/frontend/app/users/page.tsx.ejs +70 -73
- package/hedhog/frontend/messages/en.json +15 -2
- package/hedhog/frontend/messages/pt.json +15 -2
- package/package.json +4 -4
- package/src/dashboard/dashboard-core/dashboard-core.controller.ts +5 -0
- package/src/dashboard/dashboard-core/dashboard-core.service.ts +34 -0
- package/src/role/guards/role.guard.ts +9 -8
|
@@ -34,24 +34,24 @@ export default function StatOnlineTime({
|
|
|
34
34
|
widgetName={widget?.name ?? 'stat-online-time'}
|
|
35
35
|
onRemove={onRemove}
|
|
36
36
|
>
|
|
37
|
-
<Card className="h-full overflow-hidden transition-all duration-300 hover:shadow-md">
|
|
38
|
-
<CardContent className="flex h-full items-center gap-3 p-3 md:gap-4 md:p-4">
|
|
39
|
-
<div className="flex h-
|
|
40
|
-
<Clock className="h-
|
|
41
|
-
</div>
|
|
42
|
-
<div className="flex min-w-0 flex-col">
|
|
43
|
-
<span className="text-[
|
|
44
|
-
{t('onlineTime')}
|
|
45
|
-
</span>
|
|
46
|
-
<span className="truncate text-
|
|
47
|
-
{data ?? '—'}
|
|
48
|
-
</span>
|
|
49
|
-
<span className="
|
|
50
|
-
{t('onlineTimeSubtitle')}
|
|
51
|
-
</span>
|
|
52
|
-
</div>
|
|
53
|
-
</CardContent>
|
|
54
|
-
</Card>
|
|
37
|
+
<Card className="h-full overflow-hidden transition-all duration-300 hover:shadow-md">
|
|
38
|
+
<CardContent className="flex h-full items-center gap-2.5 p-2.5 sm:gap-3 sm:p-3 md:gap-4 md:p-4">
|
|
39
|
+
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-xl bg-blue-50 dark:bg-blue-950/40 sm:h-9 sm:w-9 md:h-11 md:w-11">
|
|
40
|
+
<Clock className="h-3.5 w-3.5 text-blue-600 dark:text-blue-400 sm:h-4 sm:w-4 md:h-5 md:w-5" />
|
|
41
|
+
</div>
|
|
42
|
+
<div className="flex min-w-0 flex-col">
|
|
43
|
+
<span className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground sm:text-[11px]">
|
|
44
|
+
{t('onlineTime')}
|
|
45
|
+
</span>
|
|
46
|
+
<span className="truncate text-lg font-bold tracking-tight text-foreground sm:text-xl md:text-2xl">
|
|
47
|
+
{data ?? '—'}
|
|
48
|
+
</span>
|
|
49
|
+
<span className="truncate text-[10px] text-muted-foreground sm:text-[11px]">
|
|
50
|
+
{t('onlineTimeSubtitle')}
|
|
51
|
+
</span>
|
|
52
|
+
</div>
|
|
53
|
+
</CardContent>
|
|
54
|
+
</Card>
|
|
55
55
|
</WidgetWrapper>
|
|
56
56
|
);
|
|
57
57
|
}
|
|
@@ -52,37 +52,41 @@ function RolesContent({ roles }: { roles: RoleData[] }) {
|
|
|
52
52
|
const t = useTranslations('core.DashboardPage.userRoles');
|
|
53
53
|
|
|
54
54
|
return (
|
|
55
|
-
<Card className="flex h-full min-h-0 flex-col overflow-hidden">
|
|
55
|
+
<Card className="flex h-full min-h-0 flex-col overflow-hidden">
|
|
56
56
|
<CardHeader className="shrink-0 pb-3">
|
|
57
57
|
<div className="flex items-center gap-2">
|
|
58
|
-
<Crown className="h-
|
|
58
|
+
<Crown className="h-4 w-4 text-amber-600 dark:text-amber-400 sm:h-5 sm:w-5" />
|
|
59
59
|
<div>
|
|
60
|
-
<CardTitle className="text-
|
|
60
|
+
<CardTitle className="text-sm font-semibold sm:text-base">
|
|
61
61
|
{t('title')}
|
|
62
62
|
</CardTitle>
|
|
63
|
-
<CardDescription>
|
|
63
|
+
<CardDescription className="text-xs sm:text-sm">
|
|
64
|
+
{t('description')}
|
|
65
|
+
</CardDescription>
|
|
64
66
|
</div>
|
|
65
67
|
</div>
|
|
66
68
|
</CardHeader>
|
|
67
|
-
<CardContent className="flex min-h-0 flex-1 overflow-auto pt-0">
|
|
68
|
-
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
|
69
|
+
<CardContent className="flex min-h-0 flex-1 overflow-auto pt-0">
|
|
70
|
+
<div className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
|
69
71
|
{roles.map((role, index) => {
|
|
70
72
|
const style = levelStyles[index % levelStyles.length]!;
|
|
71
73
|
return (
|
|
72
74
|
<div
|
|
73
75
|
key={role.id}
|
|
74
|
-
className={`flex items-center gap-
|
|
76
|
+
className={`flex items-center gap-2.5 rounded-xl border p-2.5 transition-all duration-200 hover:shadow-sm sm:gap-3 sm:p-3 ${style.border} ${style.bg}`}
|
|
75
77
|
>
|
|
76
78
|
<div
|
|
77
|
-
className={`flex h-
|
|
79
|
+
className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-lg sm:h-9 sm:w-9 ${style.iconBg}`}
|
|
78
80
|
>
|
|
79
|
-
<ShieldCheck
|
|
81
|
+
<ShieldCheck
|
|
82
|
+
className={`h-3.5 w-3.5 sm:h-4 sm:w-4 ${style.iconColor}`}
|
|
83
|
+
/>
|
|
80
84
|
</div>
|
|
81
85
|
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
82
|
-
<span className="text-
|
|
86
|
+
<span className="truncate text-[13px] font-medium text-foreground sm:text-sm">
|
|
83
87
|
{role.name}
|
|
84
88
|
</span>
|
|
85
|
-
<span className="text-
|
|
89
|
+
<span className="truncate text-[11px] text-muted-foreground sm:text-xs">
|
|
86
90
|
{role.slug}
|
|
87
91
|
</span>
|
|
88
92
|
</div>
|
|
@@ -86,31 +86,33 @@ function SessionsContent({ sessions }: { sessions: SessionData[] }) {
|
|
|
86
86
|
const router = useRouter();
|
|
87
87
|
|
|
88
88
|
return (
|
|
89
|
-
<Card className="flex h-full min-h-0 flex-col overflow-hidden">
|
|
90
|
-
<CardHeader className="shrink-0 pb-3">
|
|
91
|
-
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
|
92
|
-
<div className="flex min-w-0 items-center gap-2">
|
|
93
|
-
<Globe className="h-
|
|
94
|
-
<div className="min-w-0">
|
|
95
|
-
<CardTitle className="text-
|
|
96
|
-
{t('title')}
|
|
97
|
-
</CardTitle>
|
|
98
|
-
<CardDescription>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
89
|
+
<Card className="flex h-full min-h-0 flex-col overflow-hidden">
|
|
90
|
+
<CardHeader className="shrink-0 pb-3">
|
|
91
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
|
92
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
93
|
+
<Globe className="h-4 w-4 text-blue-600 sm:h-5 sm:w-5" />
|
|
94
|
+
<div className="min-w-0">
|
|
95
|
+
<CardTitle className="text-sm font-semibold sm:text-base">
|
|
96
|
+
{t('title')}
|
|
97
|
+
</CardTitle>
|
|
98
|
+
<CardDescription className="text-xs sm:text-sm">
|
|
99
|
+
{t('description')}
|
|
100
|
+
</CardDescription>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<Button
|
|
104
|
+
variant="outline"
|
|
105
|
+
size="sm"
|
|
106
|
+
onClick={() => router.push('/core/account/sessions')}
|
|
107
|
+
className="h-8 w-full shrink-0 gap-1.5 px-2.5 text-xs sm:h-9 sm:w-auto sm:text-sm"
|
|
108
|
+
>
|
|
109
|
+
<Info className="h-3.5 w-3.5" />
|
|
110
|
+
{t('moreInfo')}
|
|
111
|
+
</Button>
|
|
112
|
+
</div>
|
|
113
|
+
</CardHeader>
|
|
114
|
+
<CardContent className="flex min-h-0 flex-1 overflow-auto pt-0">
|
|
115
|
+
<div className="flex flex-col gap-2">
|
|
114
116
|
{sessions.map((session, index) => {
|
|
115
117
|
const ua = session.user_agent ?? '';
|
|
116
118
|
const deviceType = detectDeviceType(ua);
|
|
@@ -135,42 +137,42 @@ function SessionsContent({ sessions }: { sessions: SessionData[] }) {
|
|
|
135
137
|
return (
|
|
136
138
|
<div
|
|
137
139
|
key={session.id}
|
|
138
|
-
className={`group flex items-center gap-
|
|
140
|
+
className={`group flex items-center gap-2.5 rounded-xl border p-3 transition-all duration-200 hover:shadow-sm sm:gap-3 sm:p-3.5 ${
|
|
139
141
|
isCurrent
|
|
140
142
|
? 'border-emerald-200 bg-emerald-50/50 dark:border-emerald-800 dark:bg-emerald-950/30'
|
|
141
143
|
: 'bg-card hover:bg-muted/30'
|
|
142
144
|
}`}
|
|
143
145
|
>
|
|
144
146
|
<div
|
|
145
|
-
className={`flex h-
|
|
147
|
+
className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-lg sm:h-10 sm:w-10 ${
|
|
146
148
|
isCurrent
|
|
147
149
|
? 'bg-emerald-100 dark:bg-emerald-900/50'
|
|
148
150
|
: 'bg-muted'
|
|
149
151
|
}`}
|
|
150
152
|
>
|
|
151
153
|
<DeviceIcon
|
|
152
|
-
className={`h-5 w-5 ${
|
|
154
|
+
className={`h-4 w-4 sm:h-5 sm:w-5 ${
|
|
153
155
|
isCurrent
|
|
154
156
|
? 'text-emerald-600 dark:text-emerald-400'
|
|
155
157
|
: 'text-muted-foreground'
|
|
156
158
|
}`}
|
|
157
159
|
/>
|
|
158
160
|
</div>
|
|
159
|
-
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
160
|
-
<div className="flex flex-wrap items-center gap-2">
|
|
161
|
-
<span className="min-w-0 break-
|
|
162
|
-
{device}
|
|
163
|
-
</span>
|
|
161
|
+
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
|
162
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
163
|
+
<span className="min-w-0 wrap-break-word text-[13px] font-medium text-foreground sm:text-sm">
|
|
164
|
+
{device}
|
|
165
|
+
</span>
|
|
164
166
|
{isCurrent && (
|
|
165
167
|
<Badge className="bg-emerald-100 text-[10px] text-emerald-700 hover:bg-emerald-100 dark:bg-emerald-900/50 dark:text-emerald-400 dark:hover:bg-emerald-900/50">
|
|
166
168
|
{t('thisSession')}
|
|
167
169
|
</Badge>
|
|
168
170
|
)}
|
|
169
171
|
</div>
|
|
170
|
-
<span className="break-
|
|
171
|
-
{browser} · {ip}
|
|
172
|
-
</span>
|
|
173
|
-
<div className="flex flex-wrap items-center gap-
|
|
172
|
+
<span className="wrap-break-word text-[11px] text-muted-foreground sm:text-xs">
|
|
173
|
+
{browser} · {ip}
|
|
174
|
+
</span>
|
|
175
|
+
<div className="flex flex-wrap items-center gap-2 text-[10px] text-muted-foreground/70 sm:gap-3 sm:text-[11px]">
|
|
174
176
|
<span className="flex items-center gap-1">
|
|
175
177
|
<Clock className="h-3 w-3" />
|
|
176
178
|
{relativeTime}
|
|
@@ -34,8 +34,12 @@
|
|
|
34
34
|
opacity: 0.45;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
.dashboard-grid
|
|
38
|
-
.
|
|
37
|
+
.dashboard-grid
|
|
38
|
+
.react-grid-item:hover
|
|
39
|
+
> .react-resizable-handle.react-resizable-handle-se,
|
|
40
|
+
.dashboard-grid
|
|
41
|
+
.react-grid-item.resizing
|
|
42
|
+
> .react-resizable-handle.react-resizable-handle-se {
|
|
39
43
|
opacity: 1;
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -43,11 +47,15 @@
|
|
|
43
47
|
display: none;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
.dashboard-grid
|
|
50
|
+
.dashboard-grid
|
|
51
|
+
.react-grid-item
|
|
52
|
+
> .react-resizable-handle:not(.react-resizable-handle-se) {
|
|
47
53
|
display: none;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
.dashboard-grid
|
|
56
|
+
.dashboard-grid
|
|
57
|
+
.react-grid-item
|
|
58
|
+
> .react-resizable-handle.react-resizable-handle-se {
|
|
51
59
|
bottom: 0;
|
|
52
60
|
right: 0;
|
|
53
61
|
cursor: se-resize;
|
|
@@ -102,3 +110,11 @@
|
|
|
102
110
|
.dashboard-widget > [data-slot='card'] > [data-slot='card-header'] {
|
|
103
111
|
padding-top: 0;
|
|
104
112
|
}
|
|
113
|
+
|
|
114
|
+
@media (max-width: 639px) {
|
|
115
|
+
.dashboard-widget > [data-slot='card'] {
|
|
116
|
+
gap: 0.625rem;
|
|
117
|
+
padding-top: 0.625rem;
|
|
118
|
+
padding-bottom: 0.625rem;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
EmptyState,
|
|
5
|
+
Page,
|
|
6
|
+
PageHeader,
|
|
7
|
+
PaginationFooter,
|
|
8
|
+
SearchBar,
|
|
9
|
+
} from '@/components/entity-list';
|
|
4
10
|
import { Badge } from '@/components/ui/badge';
|
|
5
11
|
import { Button } from '@/components/ui/button';
|
|
6
12
|
import { Card, CardContent } from '@/components/ui/card';
|
|
@@ -11,14 +17,13 @@ import {
|
|
|
11
17
|
DialogHeader,
|
|
12
18
|
DialogTitle,
|
|
13
19
|
} from '@/components/ui/dialog';
|
|
14
|
-
import { Input } from '@/components/ui/input';
|
|
15
20
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
16
21
|
import { useDebounce } from '@/hooks/use-debounce';
|
|
17
22
|
import { formatDate } from '@/lib/format-date';
|
|
18
23
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
19
|
-
import { Clock, Mail,
|
|
24
|
+
import { Clock, Mail, User } from 'lucide-react';
|
|
20
25
|
import { useTranslations } from 'next-intl';
|
|
21
|
-
import {
|
|
26
|
+
import { useState } from 'react';
|
|
22
27
|
|
|
23
28
|
type PaginationResult<T> = {
|
|
24
29
|
data: T[];
|
|
@@ -42,7 +47,6 @@ type MailSent = {
|
|
|
42
47
|
|
|
43
48
|
export default function MailLogPage() {
|
|
44
49
|
const t = useTranslations('core.MailLog');
|
|
45
|
-
const [logs, setLogs] = useState<MailSent[]>([]);
|
|
46
50
|
const [selectedLog, setSelectedLog] = useState<MailSent | null>(null);
|
|
47
51
|
const [isDetailDialogOpen, setIsDetailDialogOpen] = useState(false);
|
|
48
52
|
const [searchTerm, setSearchTerm] = useState('');
|
|
@@ -51,10 +55,9 @@ export default function MailLogPage() {
|
|
|
51
55
|
const [pageSize, setPageSize] = useState(10);
|
|
52
56
|
const { request, getSettingValue } = useApp();
|
|
53
57
|
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
} = useQuery<PaginationResult<MailSent>>({
|
|
58
|
+
const { data: logsResult, refetch: refetchLogs } = useQuery<
|
|
59
|
+
PaginationResult<MailSent>
|
|
60
|
+
>({
|
|
58
61
|
queryKey: ['mail-sent', debouncedSearch, page, pageSize],
|
|
59
62
|
queryFn: async () => {
|
|
60
63
|
const response = await request({
|
|
@@ -67,19 +70,8 @@ export default function MailLogPage() {
|
|
|
67
70
|
});
|
|
68
71
|
return response.data as PaginationResult<MailSent>;
|
|
69
72
|
},
|
|
70
|
-
initialData: {
|
|
71
|
-
data: [],
|
|
72
|
-
total: 0,
|
|
73
|
-
page: 1,
|
|
74
|
-
pageSize: 10,
|
|
75
|
-
},
|
|
76
73
|
});
|
|
77
|
-
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
if (data) {
|
|
80
|
-
setLogs(data);
|
|
81
|
-
}
|
|
82
|
-
}, [data]);
|
|
74
|
+
const { data: logs = [], total = 0 } = logsResult ?? {};
|
|
83
75
|
|
|
84
76
|
const handleViewDetails = (log: MailSent): void => {
|
|
85
77
|
setSelectedLog(log);
|
|
@@ -98,12 +90,8 @@ export default function MailLogPage() {
|
|
|
98
90
|
: text;
|
|
99
91
|
};
|
|
100
92
|
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
refetchLogs();
|
|
103
|
-
}, [debouncedSearch, page, pageSize]);
|
|
104
|
-
|
|
105
93
|
return (
|
|
106
|
-
<
|
|
94
|
+
<Page>
|
|
107
95
|
<PageHeader
|
|
108
96
|
breadcrumbs={[
|
|
109
97
|
{ label: t('breadcrumbHome'), href: '/' },
|
|
@@ -147,29 +135,30 @@ export default function MailLogPage() {
|
|
|
147
135
|
</Card>
|
|
148
136
|
</div>
|
|
149
137
|
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
className="pl-10"
|
|
157
|
-
/>
|
|
158
|
-
</div>
|
|
138
|
+
<SearchBar
|
|
139
|
+
searchQuery={searchTerm}
|
|
140
|
+
onSearchChange={handleSearchChange}
|
|
141
|
+
onSearch={() => setPage(1)}
|
|
142
|
+
placeholder={t('searchPlaceholder')}
|
|
143
|
+
/>
|
|
159
144
|
|
|
160
145
|
<div className="space-y-3 mb-4">
|
|
161
146
|
{logs.length === 0 ? (
|
|
162
|
-
<
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
147
|
+
<EmptyState
|
|
148
|
+
icon={<Mail className="h-12 w-12" />}
|
|
149
|
+
title={t('noLogsFound')}
|
|
150
|
+
description={searchTerm ? t('adjustSearch') : t('noEmailsSent')}
|
|
151
|
+
actionLabel={searchTerm ? t('clearSearch') : t('refreshList')}
|
|
152
|
+
onAction={() => {
|
|
153
|
+
if (searchTerm) {
|
|
154
|
+
setSearchTerm('');
|
|
155
|
+
setPage(1);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
refetchLogs();
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
173
162
|
) : (
|
|
174
163
|
logs.map((log) => (
|
|
175
164
|
<Card
|
|
@@ -307,6 +296,6 @@ export default function MailLogPage() {
|
|
|
307
296
|
</DialogContent>
|
|
308
297
|
</Dialog>
|
|
309
298
|
)}
|
|
310
|
-
</
|
|
299
|
+
</Page>
|
|
311
300
|
);
|
|
312
301
|
}
|