@hed-hog/core 0.0.185 → 0.0.190
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/hedhog/frontend/app/account/2fa/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/accounts/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +356 -0
- package/hedhog/frontend/app/account/components/change-email-form.tsx.ejs +379 -0
- package/hedhog/frontend/app/account/components/change-password-form.tsx.ejs +184 -0
- package/hedhog/frontend/app/account/components/connected-accounts.tsx.ejs +144 -0
- package/hedhog/frontend/app/account/components/email-request-dialog.tsx.ejs +96 -0
- package/hedhog/frontend/app/account/components/mfa-add-buttons.tsx.ejs +43 -0
- package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +115 -0
- package/hedhog/frontend/app/account/components/mfa-setup-dialog.tsx.ejs +236 -0
- package/hedhog/frontend/app/account/components/profile-form.tsx.ejs +209 -0
- package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +192 -0
- package/hedhog/frontend/app/account/components/regenerate-codes-dialog.tsx.ejs +372 -0
- package/hedhog/frontend/app/account/components/remove-mfa-dialog.tsx.ejs +337 -0
- package/hedhog/frontend/app/account/components/two-factor-auth.tsx.ejs +393 -0
- package/hedhog/frontend/app/account/components/verify-before-add-dialog.tsx.ejs +332 -0
- package/hedhog/frontend/app/account/email/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/hooks/use-mfa-methods.ts.ejs +27 -0
- package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +461 -0
- package/hedhog/frontend/app/account/layout.tsx.ejs +105 -0
- package/hedhog/frontend/app/account/lib/mfa-utils.tsx.ejs +37 -0
- package/hedhog/frontend/app/account/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/password/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/profile/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/sessions/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +490 -0
- package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +62 -0
- package/hedhog/frontend/app/configurations/layout.tsx.ejs +316 -0
- package/hedhog/frontend/app/configurations/page.tsx.ejs +35 -0
- package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +351 -0
- package/hedhog/frontend/app/dashboard/[slug]/page.tsx.ejs +11 -0
- package/hedhog/frontend/app/dashboard/[slug]/types.ts.ejs +62 -0
- package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +45 -0
- package/hedhog/frontend/app/dashboard/dashboard.css.ejs +196 -0
- package/hedhog/frontend/app/dashboard/management/page.tsx.ejs +63 -0
- package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +516 -0
- package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +753 -0
- package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +516 -0
- package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +489 -0
- package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +621 -0
- package/hedhog/frontend/app/dashboard/page.tsx.ejs +14 -0
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +312 -0
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +1177 -0
- package/hedhog/frontend/app/preferences/page.tsx.ejs +448 -0
- package/hedhog/frontend/app/roles/menus.tsx.ejs +504 -0
- package/hedhog/frontend/app/roles/page.tsx.ejs +814 -0
- package/hedhog/frontend/app/roles/routes.tsx.ejs +397 -0
- package/hedhog/frontend/app/roles/users.tsx.ejs +306 -0
- package/hedhog/frontend/app/users/active-session.tsx.ejs +159 -0
- package/hedhog/frontend/app/users/identifiers.tsx.ejs +279 -0
- package/hedhog/frontend/app/users/page.tsx.ejs +1257 -0
- package/hedhog/frontend/app/users/permissions.tsx.ejs +155 -0
- package/hedhog/frontend/messages/en.json +1080 -0
- package/hedhog/frontend/messages/pt.json +1135 -0
- package/package.json +4 -4
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Card, CardContent } from '@/components/ui/card';
|
|
4
|
+
import { Label } from '@/components/ui/label';
|
|
5
|
+
import { Switch } from '@/components/ui/switch';
|
|
6
|
+
import { Role } from '@hed-hog/api-types';
|
|
7
|
+
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
8
|
+
import { Loader2, ShieldCheck } from 'lucide-react';
|
|
9
|
+
import { useTranslations } from 'next-intl';
|
|
10
|
+
import { useState } from 'react';
|
|
11
|
+
import { toast } from 'sonner';
|
|
12
|
+
|
|
13
|
+
type CustomRole = Role & {
|
|
14
|
+
isAssigned: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type PermissionsSectionProps = {
|
|
18
|
+
userId: number;
|
|
19
|
+
onRoleChange?: () => void;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function PermissionsSection({
|
|
23
|
+
userId,
|
|
24
|
+
onRoleChange,
|
|
25
|
+
}: PermissionsSectionProps) {
|
|
26
|
+
const t = useTranslations('core.UserPage');
|
|
27
|
+
const { request, currentLocaleCode } = useApp();
|
|
28
|
+
const [togglingRoleId, setTogglingRoleId] = useState<number | null>(null);
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
data: userRoles = [],
|
|
32
|
+
isLoading: isLoadingUserRoles,
|
|
33
|
+
refetch: refetchUserRoles,
|
|
34
|
+
} = useQuery<CustomRole[]>({
|
|
35
|
+
queryKey: ['user-roles', userId, currentLocaleCode],
|
|
36
|
+
queryFn: async () => {
|
|
37
|
+
const response = await request<CustomRole[]>({
|
|
38
|
+
url: `/user/${userId}/role`,
|
|
39
|
+
method: 'GET',
|
|
40
|
+
});
|
|
41
|
+
return response.data || [];
|
|
42
|
+
},
|
|
43
|
+
enabled: !!userId,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const handleToggleRole = async (roleId: number, isAssigned: boolean) => {
|
|
47
|
+
setTogglingRoleId(roleId);
|
|
48
|
+
try {
|
|
49
|
+
if (isAssigned) {
|
|
50
|
+
await request({
|
|
51
|
+
url: `/user/${userId}/role/${roleId}`,
|
|
52
|
+
method: 'DELETE',
|
|
53
|
+
});
|
|
54
|
+
toast.success(t('roleRemoved'));
|
|
55
|
+
} else {
|
|
56
|
+
await request({
|
|
57
|
+
url: `/user/${userId}/role/${roleId}`,
|
|
58
|
+
method: 'POST',
|
|
59
|
+
});
|
|
60
|
+
toast.success(t('roleAssigned'));
|
|
61
|
+
}
|
|
62
|
+
await refetchUserRoles();
|
|
63
|
+
onRoleChange?.();
|
|
64
|
+
} catch (error) {
|
|
65
|
+
toast.error(
|
|
66
|
+
isAssigned ? t('errorRemovingRole') : t('errorAssigningRole')
|
|
67
|
+
);
|
|
68
|
+
} finally {
|
|
69
|
+
setTogglingRoleId(null);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (isLoadingUserRoles) {
|
|
74
|
+
return (
|
|
75
|
+
<div className="flex items-center justify-center py-8">
|
|
76
|
+
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
|
77
|
+
<span className="ml-2 text-sm text-muted-foreground">
|
|
78
|
+
{t('loadingRoles')}
|
|
79
|
+
</span>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!userRoles || userRoles.length === 0) {
|
|
85
|
+
return (
|
|
86
|
+
<Card className="border-dashed">
|
|
87
|
+
<CardContent className="flex flex-col items-center justify-center py-8">
|
|
88
|
+
<ShieldCheck className="h-12 w-12 text-muted-foreground mb-3" />
|
|
89
|
+
<p className="text-sm font-medium text-center">
|
|
90
|
+
{t('noRolesAvailable')}
|
|
91
|
+
</p>
|
|
92
|
+
</CardContent>
|
|
93
|
+
</Card>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className="space-y-2">
|
|
99
|
+
{userRoles.map((role, index) => {
|
|
100
|
+
const isToggling = togglingRoleId === role.id;
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<Card
|
|
104
|
+
key={role.id ?? `role-${index}`}
|
|
105
|
+
className={`transition-all py-4 ${
|
|
106
|
+
role.isAssigned
|
|
107
|
+
? 'border-primary bg-primary/5'
|
|
108
|
+
: 'border-border hover:border-primary/50'
|
|
109
|
+
}`}
|
|
110
|
+
>
|
|
111
|
+
<CardContent className="flex items-center justify-between px-4">
|
|
112
|
+
<div className="flex items-center gap-2 flex-1">
|
|
113
|
+
<div
|
|
114
|
+
className={`rounded-md p-2 ${
|
|
115
|
+
role.isAssigned ? 'bg-primary/10' : 'bg-muted'
|
|
116
|
+
}`}
|
|
117
|
+
>
|
|
118
|
+
<ShieldCheck
|
|
119
|
+
className={`h-5 w-5 ${
|
|
120
|
+
role.isAssigned ? 'text-primary' : 'text-muted-foreground'
|
|
121
|
+
}`}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
<div className="flex-1">
|
|
125
|
+
<Label
|
|
126
|
+
htmlFor={`role-${role.id}`}
|
|
127
|
+
className={`text-sm font-medium cursor-pointer ${
|
|
128
|
+
role.isAssigned ? 'text-foreground' : 'text-foreground'
|
|
129
|
+
}`}
|
|
130
|
+
>
|
|
131
|
+
{role.name} ({role.slug})
|
|
132
|
+
</Label>
|
|
133
|
+
{role.description && (
|
|
134
|
+
<p className="text-xs text-muted-foreground">
|
|
135
|
+
{role.description}
|
|
136
|
+
</p>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
<Switch
|
|
141
|
+
id={`role-${role.id}`}
|
|
142
|
+
checked={role.isAssigned}
|
|
143
|
+
disabled={isToggling}
|
|
144
|
+
onCheckedChange={() =>
|
|
145
|
+
handleToggleRole(role.id!, role.isAssigned)
|
|
146
|
+
}
|
|
147
|
+
className="ml-4"
|
|
148
|
+
/>
|
|
149
|
+
</CardContent>
|
|
150
|
+
</Card>
|
|
151
|
+
);
|
|
152
|
+
})}
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|