@simple-auth-kit/cli 1.3.2 → 1.4.1

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 (80) hide show
  1. package/lib/copy.ts +67 -10
  2. package/package.json +1 -1
  3. package/registry/admin-apps/nextjs/shared/.husky/commit-msg +1 -0
  4. package/registry/admin-apps/nextjs/shared/.husky/pre-commit +1 -0
  5. package/registry/admin-apps/nextjs/shared/.lintstagedrc.json +4 -0
  6. package/registry/admin-apps/nextjs/shared/.prettierrc.json +3 -0
  7. package/registry/admin-apps/nextjs/shared/commitlint.config.js +5 -0
  8. package/registry/admin-apps/nextjs/shared/eslint.config.js +28 -0
  9. package/registry/admin-apps/nextjs/shared/gitignore +11 -0
  10. package/registry/admin-apps/nextjs/variants/base/package.json +11 -2
  11. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/audit-log/page.tsx +72 -16
  12. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/customers/[id]/edit/page.tsx +107 -26
  13. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/customers/[id]/page.tsx +131 -29
  14. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/languages/[id]/edit/page.tsx +111 -25
  15. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/languages/[id]/page.tsx +97 -22
  16. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/permissions/[id]/edit/page.tsx +129 -46
  17. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/permissions/[id]/page.tsx +64 -14
  18. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/roles/[id]/page.tsx +91 -22
  19. package/registry/admin-apps/nextjs/variants/base/src/app/(console)/users/[id]/edit/page.tsx +94 -23
  20. package/registry/admin-apps/nextjs/variants/workspaces/package.json +11 -2
  21. package/registry/admin-apps/nextjs/variants/workspaces/src/app/(console)/account/page.tsx +179 -41
  22. package/registry/admin-apps/react/shared/.husky/commit-msg +1 -0
  23. package/registry/admin-apps/react/shared/.husky/pre-commit +1 -0
  24. package/registry/admin-apps/react/shared/.lintstagedrc.json +4 -0
  25. package/registry/admin-apps/react/shared/.prettierrc.json +3 -0
  26. package/registry/admin-apps/react/shared/commitlint.config.js +3 -0
  27. package/registry/admin-apps/react/shared/eslint.config.js +38 -0
  28. package/registry/admin-apps/react/shared/gitignore +17 -0
  29. package/registry/admin-apps/react/variants/base/package.json +15 -2
  30. package/registry/admin-apps/react/variants/base/src/pages/CountryDetailPage.tsx +76 -19
  31. package/registry/admin-apps/react/variants/base/src/pages/CustomerDetailPage.tsx +110 -26
  32. package/registry/admin-apps/react/variants/base/src/pages/EditCountryPage.tsx +115 -29
  33. package/registry/admin-apps/react/variants/base/src/pages/EditCustomerPage.tsx +123 -31
  34. package/registry/admin-apps/react/variants/base/src/pages/EditLanguagePage.tsx +100 -24
  35. package/registry/admin-apps/react/variants/base/src/pages/EditRolePage.tsx +99 -26
  36. package/registry/admin-apps/react/variants/base/src/pages/EditUserPage.tsx +126 -31
  37. package/registry/admin-apps/react/variants/base/src/pages/LanguageDetailPage.tsx +75 -19
  38. package/registry/admin-apps/react/variants/base/src/pages/PermissionDetailPage.tsx +58 -13
  39. package/registry/admin-apps/react/variants/base/src/pages/PermissionsPage.tsx +132 -29
  40. package/registry/admin-apps/react/variants/base/src/pages/RoleDetailPage.tsx +70 -17
  41. package/registry/admin-apps/react/variants/base/src/pages/RolesPage.tsx +277 -59
  42. package/registry/admin-apps/react/variants/workspaces/package.json +15 -2
  43. package/registry/combos/express-drizzle/eslint.config.js +18 -0
  44. package/registry/combos/express-drizzle/package.json +5 -1
  45. package/registry/combos/express-drizzle/shared/src/request-context.ts +3 -0
  46. package/registry/combos/express-prisma/eslint.config.js +18 -0
  47. package/registry/combos/express-prisma/package.json +5 -1
  48. package/registry/combos/express-prisma/shared/src/request-context.ts +3 -0
  49. package/registry/combos/nestjs-drizzle/eslint.config.js +18 -0
  50. package/registry/combos/nestjs-drizzle/package.json +5 -1
  51. package/registry/combos/nestjs-drizzle/shared/src/auth.controller.ts +138 -33
  52. package/registry/combos/nestjs-drizzle/shared/src/route-tiers.ts +71 -18
  53. package/registry/combos/nestjs-prisma/eslint.config.js +18 -0
  54. package/registry/combos/nestjs-prisma/package.json +5 -1
  55. package/registry/combos/nestjs-prisma/shared/src/auth.controller.ts +148 -35
  56. package/registry/combos/nestjs-prisma/shared/src/route-tiers.ts +72 -18
  57. package/registry/mobile-apps/bare-rn/shared/.husky/commit-msg +1 -0
  58. package/registry/mobile-apps/bare-rn/shared/.husky/pre-commit +1 -0
  59. package/registry/mobile-apps/bare-rn/shared/.lintstagedrc.json +4 -0
  60. package/registry/mobile-apps/bare-rn/shared/.prettierrc.json +5 -0
  61. package/registry/mobile-apps/bare-rn/shared/commitlint.config.js +3 -0
  62. package/registry/mobile-apps/bare-rn/shared/eslint.config.js +19 -0
  63. package/registry/mobile-apps/bare-rn/shared/gitignore +78 -0
  64. package/registry/mobile-apps/bare-rn/variants/base/package.json +17 -12
  65. package/registry/mobile-apps/bare-rn/variants/workspaces/package.json +17 -12
  66. package/registry/mobile-apps/expo/shared/.husky/commit-msg +1 -0
  67. package/registry/mobile-apps/expo/shared/.husky/pre-commit +1 -0
  68. package/registry/mobile-apps/expo/shared/.lintstagedrc.json +4 -0
  69. package/registry/mobile-apps/expo/shared/.prettierrc.json +5 -0
  70. package/registry/mobile-apps/expo/shared/commitlint.config.js +3 -0
  71. package/registry/mobile-apps/expo/shared/eslint.config.js +9 -0
  72. package/registry/mobile-apps/expo/shared/gitignore +44 -0
  73. package/registry/mobile-apps/expo/shared/src/screens/SessionsScreen.tsx +6 -17
  74. package/registry/mobile-apps/expo/shared/src/store/sessionsStore.ts +35 -0
  75. package/registry/mobile-apps/expo/variants/base/package.json +12 -3
  76. package/registry/mobile-apps/expo/variants/workspaces/package.json +12 -3
  77. package/registry/mobile-apps/expo/variants/workspaces/src/screens/WorkspaceSelectScreen.tsx +1 -1
  78. package/registry.json +13 -36
  79. package/registry/mobile-apps/bare-rn/shared/.eslintrc.js +0 -4
  80. package/registry/mobile-apps/bare-rn/shared/.prettierrc.js +0 -5
@@ -1,20 +1,41 @@
1
- import { type FormEvent, useCallback, useEffect, useState } from "react";
1
+ import {
2
+ type FormEvent,
3
+ startTransition,
4
+ useCallback,
5
+ useEffect,
6
+ useState,
7
+ } from "react";
2
8
  import { useNavigate, useParams } from "react-router-dom";
3
- import { AuthApiError, type LanguageSummary, type UpdateLanguageInput } from "@simple-auth-kit/auth-client";
9
+ import {
10
+ AuthApiError,
11
+ type LanguageSummary,
12
+ type UpdateLanguageInput,
13
+ } from "@simple-auth-kit/auth-client";
4
14
  import { toast } from "sonner";
5
15
  import { authClient } from "@/lib/auth-client";
6
16
  import { errorMessage, errorMessages } from "@/lib/error";
7
17
  import { Breadcrumb } from "@/components/breadcrumb";
8
18
  import { FormErrorAlert } from "@/components/form-error-alert";
9
19
  import { Button } from "@/components/ui/button";
10
- import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
20
+ import {
21
+ Card,
22
+ CardContent,
23
+ CardDescription,
24
+ CardFooter,
25
+ CardHeader,
26
+ CardTitle,
27
+ } from "@/components/ui/card";
11
28
  import { Checkbox } from "@/components/ui/checkbox";
12
29
  import { Combobox } from "@/components/ui/combobox";
13
30
  import { Heading } from "@/components/ui/heading";
14
31
  import { Input } from "@/components/ui/input";
15
32
  import { Label } from "@/components/ui/label";
16
33
  import { Separator } from "@/components/ui/separator";
17
- import { DIRECTION_OPTIONS, emptyLanguageFields, type LanguageFormFields } from "./language-schema";
34
+ import {
35
+ DIRECTION_OPTIONS,
36
+ emptyLanguageFields,
37
+ type LanguageFormFields,
38
+ } from "./language-schema";
18
39
 
19
40
  function apiErrorMessage(err: unknown, fallback: string): string {
20
41
  return err instanceof AuthApiError ? err.message : fallback;
@@ -31,7 +52,8 @@ function toForm(language: LanguageSummary): LanguageFormFields {
31
52
  };
32
53
  }
33
54
 
34
- const inputClassName = "bg-background border-2 focus:border-purple-500 transition-colors";
55
+ const inputClassName =
56
+ "bg-background border-2 focus:border-purple-500 transition-colors";
35
57
 
36
58
  export function EditLanguagePage() {
37
59
  const { id } = useParams<{ id: string }>();
@@ -58,7 +80,7 @@ export function EditLanguagePage() {
58
80
  }, [id]);
59
81
 
60
82
  useEffect(() => {
61
- void load();
83
+ startTransition(() => void load());
62
84
  }, [load]);
63
85
 
64
86
  if (!id) return null;
@@ -101,7 +123,9 @@ export function EditLanguagePage() {
101
123
  </div>
102
124
  <Separator />
103
125
 
104
- {loading && !language && <p className="text-sm text-muted-foreground">Loading…</p>}
126
+ {loading && !language && (
127
+ <p className="text-sm text-muted-foreground">Loading…</p>
128
+ )}
105
129
 
106
130
  {language && (
107
131
  <Card>
@@ -111,13 +135,19 @@ export function EditLanguagePage() {
111
135
  <form onSubmit={handleSubmit} className="space-y-8 w-full">
112
136
  <Card className="w-full">
113
137
  <CardHeader className="border-b bg-muted/50">
114
- <CardTitle className="text-2xl">Language Information</CardTitle>
115
- <CardDescription className="text-base">Enter language details</CardDescription>
138
+ <CardTitle className="text-2xl">
139
+ Language Information
140
+ </CardTitle>
141
+ <CardDescription className="text-base">
142
+ Enter language details
143
+ </CardDescription>
116
144
  </CardHeader>
117
145
  <CardContent className="pt-6">
118
146
  <div className="space-y-6">
119
147
  <div className="space-y-4">
120
- <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">Basic Information</h3>
148
+ <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">
149
+ Basic Information
150
+ </h3>
121
151
  <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
122
152
  <div className="flex flex-col gap-2">
123
153
  <Label htmlFor="name">Language Name</Label>
@@ -127,7 +157,9 @@ export function EditLanguagePage() {
127
157
  placeholder="e.g., English"
128
158
  required
129
159
  value={form.name}
130
- onChange={(e) => setForm({ ...form, name: e.target.value })}
160
+ onChange={(e) =>
161
+ setForm({ ...form, name: e.target.value })
162
+ }
131
163
  type="text"
132
164
  className={inputClassName}
133
165
  />
@@ -135,7 +167,9 @@ export function EditLanguagePage() {
135
167
  <div className="flex flex-col gap-2">
136
168
  <Label htmlFor="code">
137
169
  Language Code &nbsp;
138
- <span className="text-xs text-destructive dark:text-destructive-foreground">(ISO code, e.g., en, ar, bn)</span>
170
+ <span className="text-xs text-destructive dark:text-destructive-foreground">
171
+ (ISO code, e.g., en, ar, bn)
172
+ </span>
139
173
  </Label>
140
174
  <Input
141
175
  id="code"
@@ -143,7 +177,12 @@ export function EditLanguagePage() {
143
177
  placeholder="e.g., en"
144
178
  required
145
179
  value={form.code}
146
- onChange={(e) => setForm({ ...form, code: e.target.value.toLowerCase() })}
180
+ onChange={(e) =>
181
+ setForm({
182
+ ...form,
183
+ code: e.target.value.toLowerCase(),
184
+ })
185
+ }
147
186
  type="text"
148
187
  maxLength={10}
149
188
  className={`${inputClassName} lowercase`}
@@ -152,7 +191,9 @@ export function EditLanguagePage() {
152
191
  <div className="flex flex-col gap-2">
153
192
  <Label htmlFor="nativeName">
154
193
  Native Name &nbsp;
155
- <span className="text-xs text-muted-foreground">(e.g., العربية, বাংলা)</span>
194
+ <span className="text-xs text-muted-foreground">
195
+ (e.g., العربية, বাংলা)
196
+ </span>
156
197
  </Label>
157
198
  <Input
158
199
  id="nativeName"
@@ -160,7 +201,9 @@ export function EditLanguagePage() {
160
201
  placeholder="e.g., English"
161
202
  required
162
203
  value={form.nativeName}
163
- onChange={(e) => setForm({ ...form, nativeName: e.target.value })}
204
+ onChange={(e) =>
205
+ setForm({ ...form, nativeName: e.target.value })
206
+ }
164
207
  type="text"
165
208
  className={inputClassName}
166
209
  />
@@ -171,7 +214,12 @@ export function EditLanguagePage() {
171
214
  options={DIRECTION_OPTIONS}
172
215
  selected={form.direction}
173
216
  placeholder="Select text direction"
174
- onChange={(option) => setForm({ ...form, direction: option.value as "ltr" | "rtl" })}
217
+ onChange={(option) =>
218
+ setForm({
219
+ ...form,
220
+ direction: option.value as "ltr" | "rtl",
221
+ })
222
+ }
175
223
  showCreate={false}
176
224
  popoverClassName="min-w-[250px]"
177
225
  />
@@ -183,26 +231,54 @@ export function EditLanguagePage() {
183
231
 
184
232
  <div className="flex flex-wrap justify-center gap-4 mt-6">
185
233
  <label className="flex flex-row items-center space-x-3 rounded-lg border border-purple-500 bg-purple-50 dark:bg-purple-950/20 p-4">
186
- <Checkbox checked={form.isDefault} onCheckedChange={(checked) => setForm({ ...form, isDefault: checked === true })} />
234
+ <Checkbox
235
+ checked={form.isDefault}
236
+ onCheckedChange={(checked) =>
237
+ setForm({ ...form, isDefault: checked === true })
238
+ }
239
+ />
187
240
  <span className="space-y-1 leading-none">
188
- <span className="block text-base font-medium">Default Language</span>
189
- <span className="block text-sm text-muted-foreground">The default language is the one a new deployment&apos;s locale falls back to</span>
241
+ <span className="block text-base font-medium">
242
+ Default Language
243
+ </span>
244
+ <span className="block text-sm text-muted-foreground">
245
+ The default language is the one a new deployment&apos;s
246
+ locale falls back to
247
+ </span>
190
248
  </span>
191
249
  </label>
192
250
  <label className="flex flex-row items-center space-x-3 rounded-lg border border-purple-500 bg-purple-50 dark:bg-purple-950/20 p-4">
193
- <Checkbox checked={form.isActive} onCheckedChange={(checked) => setForm({ ...form, isActive: checked === true })} />
251
+ <Checkbox
252
+ checked={form.isActive}
253
+ onCheckedChange={(checked) =>
254
+ setForm({ ...form, isActive: checked === true })
255
+ }
256
+ />
194
257
  <span className="space-y-1 leading-none">
195
- <span className="block text-base font-medium">Active Status</span>
196
- <span className="block text-sm text-muted-foreground">Language will be active and available for selection</span>
258
+ <span className="block text-base font-medium">
259
+ Active Status
260
+ </span>
261
+ <span className="block text-sm text-muted-foreground">
262
+ Language will be active and available for selection
263
+ </span>
197
264
  </span>
198
265
  </label>
199
266
  </div>
200
267
 
201
268
  <CardFooter className="flex justify-center gap-4 mt-8 pb-8">
202
- <Button type="button" variant="outline" onClick={() => navigate(`/languages/${id}`)} disabled={saving}>
269
+ <Button
270
+ type="button"
271
+ variant="outline"
272
+ onClick={() => navigate(`/languages/${id}`)}
273
+ disabled={saving}
274
+ >
203
275
  Cancel
204
276
  </Button>
205
- <Button disabled={saving} className="bg-purple-600 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-700 min-w-32" type="submit">
277
+ <Button
278
+ disabled={saving}
279
+ className="bg-purple-600 hover:bg-purple-700 dark:bg-purple-600 dark:hover:bg-purple-700 min-w-32"
280
+ type="submit"
281
+ >
206
282
  {saving ? "Updating..." : "Update Language"}
207
283
  </Button>
208
284
  </CardFooter>
@@ -1,6 +1,15 @@
1
- import { type FormEvent, useCallback, useEffect, useState } from "react";
1
+ import {
2
+ type FormEvent,
3
+ startTransition,
4
+ useCallback,
5
+ useEffect,
6
+ useState,
7
+ } from "react";
2
8
  import { useNavigate, useParams } from "react-router-dom";
3
- import type { PermissionSummary, RoleSummary } from "@simple-auth-kit/auth-client";
9
+ import type {
10
+ PermissionSummary,
11
+ RoleSummary,
12
+ } from "@simple-auth-kit/auth-client";
4
13
  import { AuthApiError } from "@simple-auth-kit/auth-client";
5
14
  import { toast } from "sonner";
6
15
  import { PERMISSIONS, useAbility } from "@/lib/ability";
@@ -10,7 +19,14 @@ import { Breadcrumb } from "@/components/breadcrumb";
10
19
  import { FormErrorAlert } from "@/components/form-error-alert";
11
20
  import { PermissionGroupSelect } from "@/components/permission-group-select";
12
21
  import { Button } from "@/components/ui/button";
13
- import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
22
+ import {
23
+ Card,
24
+ CardContent,
25
+ CardDescription,
26
+ CardFooter,
27
+ CardHeader,
28
+ CardTitle,
29
+ } from "@/components/ui/card";
14
30
  import { Checkbox } from "@/components/ui/checkbox";
15
31
  import { Heading } from "@/components/ui/heading";
16
32
  import { Input } from "@/components/ui/input";
@@ -25,13 +41,17 @@ function sameSlugs(a: string[], b: string[]): boolean {
25
41
  return JSON.stringify([...a].sort()) === JSON.stringify([...b].sort());
26
42
  }
27
43
 
28
- const inputClassName = "bg-background border-2 focus:border-purple-500 transition-colors";
44
+ const inputClassName =
45
+ "bg-background border-2 focus:border-purple-500 transition-colors";
29
46
 
30
47
  export function EditRolePage() {
31
48
  const { id } = useParams<{ id: string }>();
32
49
  const navigate = useNavigate();
33
50
  const ability = useAbility();
34
- const canReadPermissions = ability.can(PERMISSIONS.permissionsRead, "permission");
51
+ const canReadPermissions = ability.can(
52
+ PERMISSIONS.permissionsRead,
53
+ "permission",
54
+ );
35
55
 
36
56
  const [role, setRole] = useState<RoleSummary | null>(null);
37
57
  const [loading, setLoading] = useState(false);
@@ -40,7 +60,9 @@ export function EditRolePage() {
40
60
  const [isDefault, setIsDefault] = useState(false);
41
61
  const [isActive, setIsActive] = useState(true);
42
62
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([]);
43
- const [permissionCatalog, setPermissionCatalog] = useState<PermissionSummary[]>([]);
63
+ const [permissionCatalog, setPermissionCatalog] = useState<
64
+ PermissionSummary[]
65
+ >([]);
44
66
  const [formError, setFormError] = useState<string[] | null>(null);
45
67
  const [saving, setSaving] = useState(false);
46
68
 
@@ -70,7 +92,7 @@ export function EditRolePage() {
70
92
  }, [id]);
71
93
 
72
94
  useEffect(() => {
73
- void load();
95
+ startTransition(() => void load());
74
96
  }, [load]);
75
97
 
76
98
  useEffect(() => {
@@ -78,7 +100,11 @@ export function EditRolePage() {
78
100
  authClient
79
101
  .listPermissions({ activeOnly: true })
80
102
  .then(setPermissionCatalog)
81
- .catch((err) => toast.error(apiErrorMessage(err, "Couldn't load the permission catalog.")));
103
+ .catch((err) =>
104
+ toast.error(
105
+ apiErrorMessage(err, "Couldn't load the permission catalog."),
106
+ ),
107
+ );
82
108
  }, [canReadPermissions]);
83
109
 
84
110
  const unchanged =
@@ -96,8 +122,12 @@ export function EditRolePage() {
96
122
  setSaving(true);
97
123
  try {
98
124
  // No bulk "set permissions" endpoint — diffs against the role loaded at mount and attaches/detaches only the delta.
99
- const toAttach = selectedPermissions.filter((slug) => !role.permissions.includes(slug));
100
- const toDetach = role.permissions.filter((slug) => !selectedPermissions.includes(slug));
125
+ const toAttach = selectedPermissions.filter(
126
+ (slug) => !role.permissions.includes(slug),
127
+ );
128
+ const toDetach = role.permissions.filter(
129
+ (slug) => !selectedPermissions.includes(slug),
130
+ );
101
131
  const [updated] = await Promise.all([
102
132
  authClient.updateRole(role.id, {
103
133
  displayName: displayName.trim() === "" ? undefined : displayName,
@@ -105,14 +135,20 @@ export function EditRolePage() {
105
135
  isDefault,
106
136
  isActive,
107
137
  }),
108
- ...toAttach.map((slug) => authClient.attachPermissionToRole(role.id, slug)),
109
- ...toDetach.map((slug) => authClient.detachPermissionFromRole(role.id, slug)),
138
+ ...toAttach.map((slug) =>
139
+ authClient.attachPermissionToRole(role.id, slug),
140
+ ),
141
+ ...toDetach.map((slug) =>
142
+ authClient.detachPermissionFromRole(role.id, slug),
143
+ ),
110
144
  ]);
111
145
  toast.success(`Role "${updated.name}" updated.`);
112
146
  navigate("/roles");
113
147
  } catch (err) {
114
148
  setFormError(errorMessages(err));
115
- toast.error(apiErrorMessage(err, "Couldn't update this role. Try again."));
149
+ toast.error(
150
+ apiErrorMessage(err, "Couldn't update this role. Try again."),
151
+ );
116
152
  setSaving(false);
117
153
  }
118
154
  }
@@ -131,7 +167,9 @@ export function EditRolePage() {
131
167
  </div>
132
168
  <Separator />
133
169
 
134
- {loading && !role && <p className="text-sm text-muted-foreground">Loading…</p>}
170
+ {loading && !role && (
171
+ <p className="text-sm text-muted-foreground">Loading…</p>
172
+ )}
135
173
 
136
174
  {role && (
137
175
  <Card>
@@ -142,12 +180,16 @@ export function EditRolePage() {
142
180
  <Card className="w-full">
143
181
  <CardHeader className="border-b bg-muted/50">
144
182
  <CardTitle className="text-2xl">Role Information</CardTitle>
145
- <CardDescription className="text-base">{role.name}</CardDescription>
183
+ <CardDescription className="text-base">
184
+ {role.name}
185
+ </CardDescription>
146
186
  </CardHeader>
147
187
  <CardContent className="pt-6">
148
188
  <div className="space-y-6">
149
189
  <div className="space-y-4">
150
- <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">Basic Information</h3>
190
+ <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">
191
+ Basic Information
192
+ </h3>
151
193
  <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
152
194
  <div className="flex flex-col gap-2">
153
195
  <Label htmlFor="displayName">Display Name</Label>
@@ -182,12 +224,20 @@ export function EditRolePage() {
182
224
  <>
183
225
  <CardHeader className="border-b bg-muted/50 mt-6">
184
226
  <CardTitle className="text-2xl">Permissions</CardTitle>
185
- <CardDescription className="text-base">Pick the permissions this role grants</CardDescription>
227
+ <CardDescription className="text-base">
228
+ Pick the permissions this role grants
229
+ </CardDescription>
186
230
  </CardHeader>
187
231
  <CardContent className="pt-6">
188
232
  <div className="space-y-4">
189
- <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">Permissions</h3>
190
- <PermissionGroupSelect permissions={permissionCatalog} selected={selectedPermissions} onChange={setSelectedPermissions} />
233
+ <h3 className="text-sm font-semibold text-muted-foreground uppercase tracking-wide">
234
+ Permissions
235
+ </h3>
236
+ <PermissionGroupSelect
237
+ permissions={permissionCatalog}
238
+ selected={selectedPermissions}
239
+ onChange={setSelectedPermissions}
240
+ />
191
241
  </div>
192
242
  </CardContent>
193
243
  </>
@@ -195,23 +245,46 @@ export function EditRolePage() {
195
245
 
196
246
  <div className="flex flex-wrap justify-center gap-4 mt-6">
197
247
  <label className="flex flex-row items-center space-x-3 rounded-lg border border-purple-500 bg-purple-50 dark:bg-purple-950/20 p-4">
198
- <Checkbox checked={isDefault} onCheckedChange={(checked) => setIsDefault(checked === true)} />
248
+ <Checkbox
249
+ checked={isDefault}
250
+ onCheckedChange={(checked) =>
251
+ setIsDefault(checked === true)
252
+ }
253
+ />
199
254
  <span className="space-y-1 leading-none">
200
- <span className="block text-base font-medium">Default Role</span>
201
- <span className="block text-sm text-muted-foreground">Given to every newly signed-up user</span>
255
+ <span className="block text-base font-medium">
256
+ Default Role
257
+ </span>
258
+ <span className="block text-sm text-muted-foreground">
259
+ Given to every newly signed-up user
260
+ </span>
202
261
  </span>
203
262
  </label>
204
263
  <label className="flex flex-row items-center space-x-3 rounded-lg border border-purple-500 bg-purple-50 dark:bg-purple-950/20 p-4">
205
- <Checkbox checked={isActive} onCheckedChange={(checked) => setIsActive(checked === true)} />
264
+ <Checkbox
265
+ checked={isActive}
266
+ onCheckedChange={(checked) =>
267
+ setIsActive(checked === true)
268
+ }
269
+ />
206
270
  <span className="space-y-1 leading-none">
207
- <span className="block text-base font-medium">Active Status</span>
208
- <span className="block text-sm text-muted-foreground">This role will be active and can be assigned to users</span>
271
+ <span className="block text-base font-medium">
272
+ Active Status
273
+ </span>
274
+ <span className="block text-sm text-muted-foreground">
275
+ This role will be active and can be assigned to users
276
+ </span>
209
277
  </span>
210
278
  </label>
211
279
  </div>
212
280
 
213
281
  <CardFooter className="flex justify-center gap-4 mt-8 pb-8">
214
- <Button type="button" variant="outline" onClick={() => navigate("/roles")} disabled={saving}>
282
+ <Button
283
+ type="button"
284
+ variant="outline"
285
+ onClick={() => navigate("/roles")}
286
+ disabled={saving}
287
+ >
215
288
  Cancel
216
289
  </Button>
217
290
  <Button