@hed-hog/core 0.0.296 → 0.0.298

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.
Files changed (67) hide show
  1. package/dist/auth/auth.controller.d.ts +14 -14
  2. package/dist/auth/auth.service.d.ts +14 -14
  3. package/dist/challenge/challenge.service.d.ts +2 -2
  4. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +15 -1
  5. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
  6. package/dist/dashboard/dashboard-core/dashboard-core.controller.js +9 -0
  7. package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
  8. package/dist/dashboard/dashboard-core/dashboard-core.module.d.ts.map +1 -1
  9. package/dist/dashboard/dashboard-core/dashboard-core.module.js +6 -1
  10. package/dist/dashboard/dashboard-core/dashboard-core.module.js.map +1 -1
  11. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +175 -3
  12. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
  13. package/dist/dashboard/dashboard-core/dashboard-core.service.js +531 -5
  14. package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
  15. package/dist/file/file.controller.d.ts.map +1 -1
  16. package/dist/file/file.controller.js +16 -0
  17. package/dist/file/file.controller.js.map +1 -1
  18. package/dist/file/file.service.d.ts +7 -1
  19. package/dist/file/file.service.d.ts.map +1 -1
  20. package/dist/file/file.service.js +38 -1
  21. package/dist/file/file.service.js.map +1 -1
  22. package/dist/file/provider/s3.provider.d.ts +1 -0
  23. package/dist/file/provider/s3.provider.d.ts.map +1 -1
  24. package/dist/file/provider/s3.provider.js +38 -29
  25. package/dist/file/provider/s3.provider.js.map +1 -1
  26. package/dist/oauth/oauth.service.d.ts.map +1 -1
  27. package/dist/oauth/oauth.service.js +2 -1
  28. package/dist/oauth/oauth.service.js.map +1 -1
  29. package/dist/profile/profile.controller.d.ts +6 -6
  30. package/dist/profile/profile.service.d.ts +6 -6
  31. package/dist/session/session.controller.d.ts +2 -2
  32. package/dist/session/session.service.d.ts +3 -3
  33. package/dist/setting/setting.controller.d.ts +9 -9
  34. package/dist/setting/setting.service.d.ts +10 -10
  35. package/dist/user/constants/user.constants.d.ts +1 -0
  36. package/dist/user/constants/user.constants.d.ts.map +1 -1
  37. package/dist/user/constants/user.constants.js +2 -1
  38. package/dist/user/constants/user.constants.js.map +1 -1
  39. package/dist/user/user.controller.d.ts +15 -15
  40. package/dist/user/user.service.d.ts +39 -39
  41. package/dist/user/user.service.d.ts.map +1 -1
  42. package/dist/user/user.service.js +2 -1
  43. package/dist/user/user.service.js.map +1 -1
  44. package/hedhog/data/dashboard_item.yaml +11 -11
  45. package/hedhog/data/route.yaml +8 -0
  46. package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +76 -15
  47. package/hedhog/frontend/app/dashboard/components/widgets/email-notifications.tsx.ejs +85 -61
  48. package/hedhog/frontend/app/dashboard/components/widgets/locale-config.tsx.ejs +139 -280
  49. package/hedhog/frontend/app/dashboard/components/widgets/mail-config.tsx.ejs +161 -407
  50. package/hedhog/frontend/app/dashboard/components/widgets/oauth-config.tsx.ejs +150 -271
  51. package/hedhog/frontend/app/dashboard/components/widgets/profile-card.tsx.ejs +3 -3
  52. package/hedhog/frontend/app/dashboard/components/widgets/storage-config.tsx.ejs +161 -305
  53. package/hedhog/frontend/app/dashboard/components/widgets/theme-config.tsx.ejs +184 -246
  54. package/hedhog/frontend/app/dashboard/components/widgets/user-roles.tsx.ejs +12 -14
  55. package/hedhog/frontend/messages/en.json +90 -0
  56. package/hedhog/frontend/messages/pt.json +90 -0
  57. package/hedhog/table/mail_sent_user.yaml +75 -0
  58. package/package.json +4 -4
  59. package/src/dashboard/dashboard-core/dashboard-core.controller.ts +5 -0
  60. package/src/dashboard/dashboard-core/dashboard-core.module.ts +6 -1
  61. package/src/dashboard/dashboard-core/dashboard-core.service.ts +766 -3
  62. package/src/file/file.controller.ts +37 -13
  63. package/src/file/file.service.ts +47 -5
  64. package/src/file/provider/s3.provider.ts +39 -29
  65. package/src/oauth/oauth.service.ts +8 -7
  66. package/src/user/constants/user.constants.ts +1 -0
  67. package/src/user/user.service.ts +2 -1
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
3
  import { Badge } from '@/components/ui/badge';
4
- import { Button } from '@/components/ui/button';
5
4
  import {
6
5
  Card,
7
6
  CardContent,
@@ -9,301 +8,161 @@ import {
9
8
  CardHeader,
10
9
  CardTitle,
11
10
  } from '@/components/ui/card';
12
- import { Checkbox } from '@/components/ui/checkbox';
13
- import { Label } from '@/components/ui/label';
14
- import {
15
- Select,
16
- SelectContent,
17
- SelectItem,
18
- SelectTrigger,
19
- SelectValue,
20
- } from '@/components/ui/select';
21
- import { Switch } from '@/components/ui/switch';
22
- import { Calendar, CheckCircle2, Clock, Globe, Type } from 'lucide-react';
23
- import { useState } from 'react';
24
-
25
- interface Language {
26
- code: string;
27
- label: string;
28
- flag: string;
29
- enabled: boolean;
30
- }
31
-
32
- const availableLanguages: Language[] = [
33
- { code: 'pt-BR', label: 'Portugues (Brasil)', flag: '🇧🇷', enabled: true },
34
- { code: 'en-US', label: 'Ingles (EUA)', flag: '🇺🇸', enabled: true },
35
- { code: 'es-ES', label: 'Espanhol (Espanha)', flag: '🇪🇸', enabled: false },
36
- { code: 'fr-FR', label: 'Frances (Franca)', flag: '🇫🇷', enabled: false },
37
- { code: 'de-DE', label: 'Alemao (Alemanha)', flag: '🇩🇪', enabled: false },
38
- { code: 'it-IT', label: 'Italiano (Italia)', flag: '🇮🇹', enabled: false },
39
- { code: 'ja-JP', label: 'Japones (Japao)', flag: '🇯🇵', enabled: false },
40
- { code: 'zh-CN', label: 'Chines (Simplificado)', flag: '🇨🇳', enabled: false },
41
- ];
11
+ import { useWidgetData } from '@/hooks/use-widget-data';
12
+ import type {
13
+ DashboardCoreConfigOverviewData,
14
+ LocaleConfigWidgetData,
15
+ } from '@/types/widget-data';
16
+ import { Calendar, Clock, Globe, Languages } from 'lucide-react';
17
+ import { useTranslations } from 'next-intl';
18
+ import { WidgetWrapper } from '../widget-wrapper';
42
19
 
43
- const timezones = [
44
- { value: 'America/Sao_Paulo', label: 'America/Sao_Paulo (GMT-3)' },
45
- { value: 'America/New_York', label: 'America/New_York (GMT-5)' },
46
- { value: 'America/Chicago', label: 'America/Chicago (GMT-6)' },
47
- { value: 'America/Denver', label: 'America/Denver (GMT-7)' },
48
- { value: 'America/Los_Angeles', label: 'America/Los_Angeles (GMT-8)' },
49
- { value: 'Europe/London', label: 'Europe/London (GMT+0)' },
50
- { value: 'Europe/Paris', label: 'Europe/Paris (GMT+1)' },
51
- { value: 'Europe/Berlin', label: 'Europe/Berlin (GMT+1)' },
52
- { value: 'Asia/Tokyo', label: 'Asia/Tokyo (GMT+9)' },
53
- { value: 'Asia/Shanghai', label: 'Asia/Shanghai (GMT+8)' },
54
- { value: 'Australia/Sydney', label: 'Australia/Sydney (GMT+11)' },
55
- ];
56
-
57
- const dateFormats = [
58
- { value: 'DD/MM/YYYY', label: 'DD/MM/YYYY', example: '14/02/2026' },
59
- { value: 'MM/DD/YYYY', label: 'MM/DD/YYYY', example: '02/14/2026' },
60
- { value: 'YYYY-MM-DD', label: 'YYYY-MM-DD', example: '2026-02-14' },
61
- { value: 'DD.MM.YYYY', label: 'DD.MM.YYYY', example: '14.02.2026' },
62
- { value: 'DD-MM-YYYY', label: 'DD-MM-YYYY', example: '14-02-2026' },
63
- ];
64
-
65
- const timeFormats = [
66
- { value: 'HH:mm', label: '24 horas', example: '14:30' },
67
- { value: 'hh:mm A', label: '12 horas', example: '02:30 PM' },
68
- { value: 'HH:mm:ss', label: '24 horas com segundos', example: '14:30:45' },
69
- {
70
- value: 'hh:mm:ss A',
71
- label: '12 horas com segundos',
72
- example: '02:30:45 PM',
20
+ const defaultLocaleConfigData: LocaleConfigWidgetData = {
21
+ status: {
22
+ isConfigured: false,
23
+ enabledLocaleCount: 0,
24
+ disabledLocaleCount: 0,
25
+ },
26
+ settings: {
27
+ dateFormat: null,
28
+ timeFormat: null,
29
+ timezone: null,
73
30
  },
74
- ];
31
+ locales: [],
32
+ };
75
33
 
76
- export default function LocaleConfig() {
77
- const [languages, setLanguages] = useState<Language[]>(availableLanguages);
78
- const [defaultLang, setDefaultLang] = useState('pt-BR');
79
- const [timezone, setTimezone] = useState('America/Sao_Paulo');
80
- const [dateFormat, setDateFormat] = useState('DD/MM/YYYY');
81
- const [timeFormat, setTimeFormat] = useState('HH:mm');
82
- const [autoDetect, setAutoDetect] = useState(true);
34
+ interface LocaleConfigProps {
35
+ widget?: { name?: string };
36
+ onRemove?: () => void;
37
+ }
38
+
39
+ export default function LocaleConfig({ widget, onRemove }: LocaleConfigProps) {
40
+ const t = useTranslations('core.DashboardPage.localeConfig');
83
41
 
84
- const enabledLanguages = languages.filter((l) => l.enabled);
42
+ const { data, isLoading, isError, isAccessDenied } = useWidgetData<
43
+ DashboardCoreConfigOverviewData,
44
+ LocaleConfigWidgetData
45
+ >({
46
+ endpoint: '/dashboard-core/config/overview',
47
+ queryKey: 'dashboard-core-config-overview',
48
+ select: (d) => d.localeConfig,
49
+ });
85
50
 
86
- function toggleLanguage(code: string) {
87
- setLanguages((prev) =>
88
- prev.map((l) => {
89
- if (l.code === code) {
90
- if (l.enabled && l.code === defaultLang) return l;
91
- return { ...l, enabled: !l.enabled };
92
- }
93
- return l;
94
- })
95
- );
96
- }
51
+ const localeData = data ?? defaultLocaleConfigData;
52
+ const enabledLocales = localeData.locales.filter((locale) => locale.enabled);
97
53
 
98
54
  return (
99
- <Card className="h-full">
100
- <CardHeader>
101
- <div className="flex items-center justify-between">
102
- <div className="flex items-center gap-3">
103
- <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-50">
104
- <Globe className="h-5 w-5 text-indigo-600" />
55
+ <WidgetWrapper
56
+ isLoading={isLoading}
57
+ isError={isError}
58
+ isAccessDenied={isAccessDenied}
59
+ widgetName={widget?.name ?? t('title')}
60
+ onRemove={onRemove}
61
+ >
62
+ <Card className="flex h-full min-h-0 flex-col overflow-hidden">
63
+ <CardHeader className="shrink-0">
64
+ <div className="flex items-center justify-between gap-3">
65
+ <div className="flex items-center gap-3">
66
+ <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-50">
67
+ <Globe className="h-5 w-5 text-indigo-600" />
68
+ </div>
69
+ <div>
70
+ <CardTitle className="text-base">{t('title')}</CardTitle>
71
+ <CardDescription>{t('description')}</CardDescription>
72
+ </div>
105
73
  </div>
106
- <div>
107
- <CardTitle className="text-base">Localizacao</CardTitle>
108
- <CardDescription>
109
- Idiomas, fuso horario e formatos regionais
110
- </CardDescription>
111
- </div>
112
- </div>
113
- <Badge variant="secondary" className="bg-indigo-50 text-indigo-700">
114
- {enabledLanguages.length} idioma
115
- {enabledLanguages.length !== 1 ? 's' : ''}
116
- </Badge>
117
- </div>
118
- </CardHeader>
119
- <CardContent className="space-y-6">
120
- {/* Languages */}
121
- <div className="space-y-3">
122
- <div className="flex items-center gap-2">
123
- <Type className="h-4 w-4 text-muted-foreground" />
124
- <Label className="text-sm font-medium">Idiomas habilitados</Label>
74
+ <Badge
75
+ variant="secondary"
76
+ className={
77
+ localeData.status.isConfigured
78
+ ? 'bg-emerald-50 text-emerald-700'
79
+ : 'bg-amber-50 text-amber-700'
80
+ }
81
+ >
82
+ {localeData.status.isConfigured ? t('configured') : t('pending')}
83
+ </Badge>
125
84
  </div>
126
- <div className="grid grid-cols-2 gap-2">
127
- {languages.map((lang) => (
128
- <label
129
- key={lang.code}
130
- className={`flex cursor-pointer items-center gap-3 rounded-lg border p-3 transition-colors ${
131
- lang.enabled
132
- ? 'border-foreground/20 bg-foreground/2'
133
- : 'border-border hover:border-foreground/10'
134
- }`}
135
- >
136
- <Checkbox
137
- checked={lang.enabled}
138
- onCheckedChange={() => toggleLanguage(lang.code)}
139
- disabled={lang.enabled && lang.code === defaultLang}
140
- />
141
- <span className="text-base leading-none">{lang.flag}</span>
142
- <div className="flex flex-1 flex-col">
143
- <span className="text-sm font-medium">{lang.label}</span>
144
- <span className="text-xs text-muted-foreground">
145
- {lang.code}
146
- </span>
147
- </div>
148
- {lang.code === defaultLang && (
149
- <Badge variant="outline" className="text-[10px] h-5">
150
- Padrao
151
- </Badge>
152
- )}
153
- </label>
154
- ))}
85
+ </CardHeader>
86
+ <CardContent className="flex min-h-0 flex-1 flex-col gap-4 overflow-hidden pt-0">
87
+ <div className="grid grid-cols-3 gap-2">
88
+ <div className="rounded-lg border bg-muted/30 p-3 text-center">
89
+ <p className="text-[11px] text-muted-foreground">
90
+ {t('enabled')}
91
+ </p>
92
+ <p className="mt-1 text-lg font-semibold">
93
+ {localeData.status.enabledLocaleCount}
94
+ </p>
95
+ </div>
96
+ <div className="rounded-lg border bg-muted/30 p-3 text-center">
97
+ <p className="text-[11px] text-muted-foreground">
98
+ {t('disabled')}
99
+ </p>
100
+ <p className="mt-1 text-lg font-semibold">
101
+ {localeData.status.disabledLocaleCount}
102
+ </p>
103
+ </div>
104
+ <div className="rounded-lg border bg-muted/30 p-3 text-center">
105
+ <p className="text-[11px] text-muted-foreground">{t('total')}</p>
106
+ <p className="mt-1 text-lg font-semibold">
107
+ {localeData.locales.length}
108
+ </p>
109
+ </div>
155
110
  </div>
156
- </div>
157
111
 
158
- {/* Default Language */}
159
- <div className="space-y-2">
160
- <Label>Idioma padrao</Label>
161
- <Select value={defaultLang} onValueChange={setDefaultLang}>
162
- <SelectTrigger>
163
- <SelectValue />
164
- </SelectTrigger>
165
- <SelectContent>
166
- {enabledLanguages.map((lang) => (
167
- <SelectItem key={lang.code} value={lang.code}>
168
- <span className="flex items-center gap-2">
169
- <span>{lang.flag}</span>
170
- <span>{lang.label}</span>
171
- </span>
172
- </SelectItem>
173
- ))}
174
- </SelectContent>
175
- </Select>
176
- <p className="text-xs text-muted-foreground">
177
- Idioma exibido quando o idioma do usuario nao esta disponivel.
178
- </p>
179
- </div>
180
-
181
- {/* Timezone */}
182
- <div className="space-y-2">
183
- <div className="flex items-center gap-2">
184
- <Clock className="h-4 w-4 text-muted-foreground" />
185
- <Label>Fuso horario do sistema</Label>
112
+ <div className="grid gap-2 sm:grid-cols-3">
113
+ <div className="rounded-lg border p-3">
114
+ <div className="mb-1 flex items-center gap-1.5 text-xs text-muted-foreground">
115
+ <Clock className="h-3.5 w-3.5" />
116
+ {t('timezone')}
117
+ </div>
118
+ <p className="truncate font-mono text-xs">
119
+ {localeData.settings.timezone || t('notSet')}
120
+ </p>
121
+ </div>
122
+ <div className="rounded-lg border p-3">
123
+ <div className="mb-1 flex items-center gap-1.5 text-xs text-muted-foreground">
124
+ <Calendar className="h-3.5 w-3.5" />
125
+ {t('dateFormat')}
126
+ </div>
127
+ <p className="font-mono text-xs">
128
+ {localeData.settings.dateFormat || t('notSet')}
129
+ </p>
130
+ </div>
131
+ <div className="rounded-lg border p-3">
132
+ <div className="mb-1 flex items-center gap-1.5 text-xs text-muted-foreground">
133
+ <Clock className="h-3.5 w-3.5" />
134
+ {t('timeFormat')}
135
+ </div>
136
+ <p className="font-mono text-xs">
137
+ {localeData.settings.timeFormat || t('notSet')}
138
+ </p>
139
+ </div>
186
140
  </div>
187
- <Select value={timezone} onValueChange={setTimezone}>
188
- <SelectTrigger>
189
- <SelectValue />
190
- </SelectTrigger>
191
- <SelectContent>
192
- {timezones.map((tz) => (
193
- <SelectItem key={tz.value} value={tz.value}>
194
- {tz.label}
195
- </SelectItem>
196
- ))}
197
- </SelectContent>
198
- </Select>
199
- </div>
200
141
 
201
- {/* Date & Time Formats */}
202
- <div className="grid gap-4 sm:grid-cols-2">
203
- <div className="space-y-2">
204
- <div className="flex items-center gap-2">
205
- <Calendar className="h-4 w-4 text-muted-foreground" />
206
- <Label>Formato de data</Label>
142
+ <div className="min-h-0 flex-1 rounded-lg border p-3">
143
+ <div className="mb-2 flex items-center gap-2 text-xs text-muted-foreground">
144
+ <Languages className="h-3.5 w-3.5" />
145
+ <span>{t('enabledLocales')}</span>
207
146
  </div>
208
- <Select value={dateFormat} onValueChange={setDateFormat}>
209
- <SelectTrigger>
210
- <SelectValue />
211
- </SelectTrigger>
212
- <SelectContent>
213
- {dateFormats.map((df) => (
214
- <SelectItem key={df.value} value={df.value}>
215
- <span className="flex items-center gap-2">
216
- <span className="font-mono text-xs">{df.value}</span>
217
- <span className="text-muted-foreground">
218
- {'('}
219
- {df.example}
220
- {')'}
221
- </span>
147
+ <div className="flex flex-wrap gap-1.5">
148
+ {enabledLocales.length > 0 ? (
149
+ enabledLocales.map((locale) => (
150
+ <Badge key={locale.id} variant="outline" className="gap-1">
151
+ <span className="font-mono text-[10px]">{locale.code}</span>
152
+ <span className="text-[10px] text-muted-foreground">
153
+ {locale.name}
222
154
  </span>
223
- </SelectItem>
224
- ))}
225
- </SelectContent>
226
- </Select>
227
- </div>
228
- <div className="space-y-2">
229
- <div className="flex items-center gap-2">
230
- <Clock className="h-4 w-4 text-muted-foreground" />
231
- <Label>Formato de hora</Label>
155
+ </Badge>
156
+ ))
157
+ ) : (
158
+ <span className="text-xs text-muted-foreground">
159
+ {t('noneEnabled')}
160
+ </span>
161
+ )}
232
162
  </div>
233
- <Select value={timeFormat} onValueChange={setTimeFormat}>
234
- <SelectTrigger>
235
- <SelectValue />
236
- </SelectTrigger>
237
- <SelectContent>
238
- {timeFormats.map((tf) => (
239
- <SelectItem key={tf.value} value={tf.value}>
240
- <span className="flex items-center gap-2">
241
- <span>{tf.label}</span>
242
- <span className="text-muted-foreground font-mono text-xs">
243
- {'('}
244
- {tf.example}
245
- {')'}
246
- </span>
247
- </span>
248
- </SelectItem>
249
- ))}
250
- </SelectContent>
251
- </Select>
252
- </div>
253
- </div>
254
-
255
- {/* Preview */}
256
- <div className="rounded-lg border bg-muted/50 p-4">
257
- <p className="mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wider">
258
- Pre-visualizacao
259
- </p>
260
- <div className="flex flex-wrap gap-x-6 gap-y-1 text-sm">
261
- <span>
262
- <span className="text-muted-foreground">Data: </span>
263
- <span className="font-medium font-mono">
264
- {dateFormats.find((d) => d.value === dateFormat)?.example}
265
- </span>
266
- </span>
267
- <span>
268
- <span className="text-muted-foreground">Hora: </span>
269
- <span className="font-medium font-mono">
270
- {timeFormats.find((t) => t.value === timeFormat)?.example}
271
- </span>
272
- </span>
273
- <span>
274
- <span className="text-muted-foreground">Fuso: </span>
275
- <span className="font-medium font-mono">
276
- {
277
- timezones
278
- .find((t) => t.value === timezone)
279
- ?.label.split(' ')[0]
280
- }
281
- </span>
282
- </span>
283
- </div>
284
- </div>
285
-
286
- {/* Actions */}
287
- <div className="flex items-center justify-between border-t pt-4">
288
- <div className="flex items-center gap-2">
289
- <Switch
290
- id="auto-detect-lang"
291
- checked={autoDetect}
292
- onCheckedChange={setAutoDetect}
293
- />
294
- <Label
295
- htmlFor="auto-detect-lang"
296
- className="text-sm text-muted-foreground"
297
- >
298
- Detectar idioma do navegador
299
- </Label>
300
163
  </div>
301
- <Button size="sm">
302
- <CheckCircle2 className="mr-1.5 h-3.5 w-3.5" />
303
- Salvar
304
- </Button>
305
- </div>
306
- </CardContent>
307
- </Card>
164
+ </CardContent>
165
+ </Card>
166
+ </WidgetWrapper>
308
167
  );
309
168
  }