@carlonicora/nextjs-jsonapi 1.36.1 → 1.38.0

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 (190) hide show
  1. package/dist/{BlockNoteEditor-4MDHRUS2.js → BlockNoteEditor-3S2B36O3.js} +15 -15
  2. package/dist/{BlockNoteEditor-4MDHRUS2.js.map → BlockNoteEditor-3S2B36O3.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-SZWO3MDO.mjs → BlockNoteEditor-WQUJTVJL.mjs} +5 -5
  4. package/dist/BlockNoteEditor-WQUJTVJL.mjs.map +1 -0
  5. package/dist/billing/index.d.mts +15 -5
  6. package/dist/billing/index.d.ts +15 -5
  7. package/dist/billing/index.js +750 -520
  8. package/dist/billing/index.js.map +1 -1
  9. package/dist/billing/index.mjs +665 -435
  10. package/dist/billing/index.mjs.map +1 -1
  11. package/dist/{chunk-53IPQJVH.js → chunk-3EZX4G2E.js} +147 -23
  12. package/dist/chunk-3EZX4G2E.js.map +1 -0
  13. package/dist/{chunk-I7DFEJFF.mjs → chunk-4PHADEKA.mjs} +738 -1418
  14. package/dist/chunk-4PHADEKA.mjs.map +1 -0
  15. package/dist/{chunk-E6PQQTWF.js → chunk-T2JCZYWK.js} +999 -1679
  16. package/dist/chunk-T2JCZYWK.js.map +1 -0
  17. package/dist/{chunk-P7R2DPD6.mjs → chunk-TQ5GRRTM.mjs} +125 -1
  18. package/dist/chunk-TQ5GRRTM.mjs.map +1 -0
  19. package/dist/client/index.js +3 -3
  20. package/dist/client/index.mjs +2 -2
  21. package/dist/components/index.d.mts +23 -8
  22. package/dist/components/index.d.ts +23 -8
  23. package/dist/components/index.js +3 -3
  24. package/dist/components/index.mjs +2 -2
  25. package/dist/contexts/index.d.mts +1 -1
  26. package/dist/contexts/index.d.ts +1 -1
  27. package/dist/contexts/index.js +3 -3
  28. package/dist/contexts/index.mjs +2 -2
  29. package/dist/core/index.d.mts +47 -3
  30. package/dist/core/index.d.ts +47 -3
  31. package/dist/core/index.js +8 -2
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/index.mjs +7 -1
  34. package/dist/index.d.mts +2 -2
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.js +8 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +7 -1
  39. package/dist/server/index.js +3 -3
  40. package/dist/server/index.mjs +1 -1
  41. package/dist/{stripe-subscription.interface-DK7BJaNd.d.ts → stripe-promotion-code.interface-BcJty0rv.d.ts} +18 -1
  42. package/dist/{stripe-subscription.interface-C8uhCYIZ.d.mts → stripe-promotion-code.interface-Dnm2DJKQ.d.mts} +18 -1
  43. package/dist/testing/index.js.map +1 -1
  44. package/dist/testing/index.mjs.map +1 -1
  45. package/package.json +2 -2
  46. package/src/billing/index.ts +1 -0
  47. package/src/client/context/JsonApiProvider.tsx +1 -5
  48. package/src/client/hooks/__tests__/useJsonApiGet.test.tsx +9 -9
  49. package/src/client/hooks/__tests__/useJsonApiMutation.test.tsx +11 -11
  50. package/src/client/hooks/__tests__/useRehydration.test.ts +13 -34
  51. package/src/components/editors/BlockNoteEditor.tsx +2 -2
  52. package/src/components/forms/CommonEditorTrigger.tsx +1 -1
  53. package/src/components/forms/FormCheckbox.tsx +2 -12
  54. package/src/components/forms/FormDate.tsx +1 -6
  55. package/src/components/forms/FormInput.tsx +1 -1
  56. package/src/components/forms/FormPassword.tsx +1 -7
  57. package/src/components/forms/FormSelect.tsx +2 -8
  58. package/src/components/forms/FormSlider.tsx +1 -5
  59. package/src/components/forms/FormSwitch.tsx +1 -5
  60. package/src/components/forms/GdprConsentCheckbox.tsx +2 -8
  61. package/src/components/forms/PasswordInput.tsx +28 -26
  62. package/src/components/forms/__tests__/FormCheckbox.test.tsx +16 -18
  63. package/src/components/forms/__tests__/FormDate.test.tsx +14 -30
  64. package/src/components/forms/__tests__/FormInput.test.tsx +21 -37
  65. package/src/components/forms/__tests__/FormSelect.test.tsx +15 -21
  66. package/src/components/tables/ContentListTable.tsx +1 -1
  67. package/src/components/tables/__tests__/ContentListTable.test.tsx +17 -89
  68. package/src/components/tables/cells/cell.component.tsx +1 -1
  69. package/src/contexts/HeaderChildrenContext.tsx +3 -1
  70. package/src/core/endpoint/__tests__/EndpointCreator.test.ts +2 -7
  71. package/src/core/factories/__tests__/JsonApiDataFactory.test.ts +3 -3
  72. package/src/core/factories/__tests__/RehydrationFactory.test.ts +4 -6
  73. package/src/core/index.ts +1 -0
  74. package/src/core/registry/ModuleRegistry.ts +1 -0
  75. package/src/core/registry/__tests__/DataClassRegistry.test.ts +5 -15
  76. package/src/core/registry/__tests__/ModuleRegistrar.test.ts +5 -15
  77. package/src/features/auth/components/GdprConsentSection.tsx +1 -6
  78. package/src/features/auth/components/details/LandingComponent.tsx +6 -1
  79. package/src/features/auth/components/forms/AcceptInvitation.tsx +1 -1
  80. package/src/features/auth/components/forms/ResetPassword.tsx +1 -1
  81. package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +13 -18
  82. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +12 -17
  83. package/src/features/billing/components/modals/BillingDetailModal.tsx +2 -13
  84. package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +8 -1
  85. package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +2 -13
  86. package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +2 -12
  87. package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +6 -1
  88. package/src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts +1 -0
  89. package/src/features/billing/stripe-price/components/lists/PricesList.tsx +13 -5
  90. package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +5 -5
  91. package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +108 -0
  92. package/src/features/billing/stripe-promotion-code/components/index.ts +1 -0
  93. package/src/features/billing/stripe-promotion-code/data/index.ts +3 -0
  94. package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.interface.ts +14 -0
  95. package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.service.ts +64 -0
  96. package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.ts +66 -0
  97. package/src/features/billing/stripe-promotion-code/index.ts +2 -0
  98. package/src/features/billing/stripe-promotion-code/stripe-promotion-code.module.ts +9 -0
  99. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +1 -3
  100. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +4 -1
  101. package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +1 -1
  102. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +24 -4
  103. package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +9 -2
  104. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +3 -1
  105. package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +7 -7
  106. package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +2 -10
  107. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +3 -13
  108. package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +134 -23
  109. package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +2 -0
  110. package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +8 -0
  111. package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +93 -7
  112. package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +1 -1
  113. package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +1 -1
  114. package/src/features/company/components/details/CompanyDetails.tsx +2 -2
  115. package/src/features/company/components/forms/CompanyConfigurationSecurityForm.tsx +1 -1
  116. package/src/features/index.ts +1 -0
  117. package/src/features/notification/components/containers/NotificationsListContainer.tsx +1 -1
  118. package/src/features/notification/components/modals/NotificationModal.tsx +6 -2
  119. package/src/features/notification/contexts/NotificationContext.tsx +1 -3
  120. package/src/features/oauth/components/OAuthClientCard.tsx +15 -17
  121. package/src/features/oauth/components/OAuthClientDetail.tsx +7 -19
  122. package/src/features/oauth/components/OAuthClientForm.tsx +4 -13
  123. package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +4 -20
  124. package/src/features/oauth/components/OAuthRedirectUriInput.tsx +5 -12
  125. package/src/features/oauth/components/OAuthScopeSelector.tsx +17 -23
  126. package/src/features/oauth/components/consent/OAuthConsentActions.tsx +3 -16
  127. package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +3 -12
  128. package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +5 -20
  129. package/src/features/oauth/components/consent/OAuthScopeList.tsx +3 -18
  130. package/src/features/onboarding/contexts/OnboardingContext.tsx +3 -3
  131. package/src/features/role/components/forms/FormRoles.tsx +1 -7
  132. package/src/features/user/components/containers/UserContainer.tsx +1 -1
  133. package/src/features/user/components/details/UserDetails.tsx +1 -1
  134. package/src/features/user/components/forms/UserDeleter.tsx +1 -1
  135. package/src/features/user/components/forms/UserEditor.tsx +1 -1
  136. package/src/features/user/components/forms/UserMultiSelect.tsx +7 -7
  137. package/src/features/user/components/lists/UserListInAdd.tsx +2 -2
  138. package/src/features/user/components/lists/UsersList.tsx +7 -1
  139. package/src/features/user/contexts/CurrentUserContext.tsx +36 -33
  140. package/src/hooks/__tests__/useDataListRetriever.test.ts +15 -21
  141. package/src/hooks/__tests__/useDebounce.test.ts +2 -7
  142. package/src/hooks/useCustomD3Graph.tsx +2 -2
  143. package/src/shadcnui/custom/multi-select.tsx +28 -2
  144. package/src/shadcnui/ui/accordion.tsx +21 -23
  145. package/src/shadcnui/ui/alert-dialog.tsx +45 -62
  146. package/src/shadcnui/ui/alert.tsx +25 -41
  147. package/src/shadcnui/ui/avatar.tsx +23 -36
  148. package/src/shadcnui/ui/badge.tsx +13 -11
  149. package/src/shadcnui/ui/breadcrumb.tsx +21 -55
  150. package/src/shadcnui/ui/button.tsx +17 -18
  151. package/src/shadcnui/ui/calendar.tsx +44 -93
  152. package/src/shadcnui/ui/carousel.tsx +72 -100
  153. package/src/shadcnui/ui/chart.tsx +102 -161
  154. package/src/shadcnui/ui/checkbox.tsx +8 -9
  155. package/src/shadcnui/ui/combobox.tsx +52 -83
  156. package/src/shadcnui/ui/command.tsx +43 -77
  157. package/src/shadcnui/ui/context-menu.tsx +47 -86
  158. package/src/shadcnui/ui/dialog.tsx +34 -60
  159. package/src/shadcnui/ui/drawer.tsx +32 -53
  160. package/src/shadcnui/ui/dropdown-menu.tsx +48 -65
  161. package/src/shadcnui/ui/field.tsx +39 -48
  162. package/src/shadcnui/ui/hover-card.tsx +9 -14
  163. package/src/shadcnui/ui/input-group.tsx +44 -55
  164. package/src/shadcnui/ui/input-otp.tsx +22 -26
  165. package/src/shadcnui/ui/input.tsx +6 -6
  166. package/src/shadcnui/ui/label.tsx +6 -6
  167. package/src/shadcnui/ui/navigation-menu.tsx +36 -60
  168. package/src/shadcnui/ui/popover.tsx +15 -38
  169. package/src/shadcnui/ui/progress.tsx +12 -29
  170. package/src/shadcnui/ui/radio-group.tsx +9 -15
  171. package/src/shadcnui/ui/resizable.tsx +14 -24
  172. package/src/shadcnui/ui/scroll-area.tsx +12 -27
  173. package/src/shadcnui/ui/select.tsx +41 -65
  174. package/src/shadcnui/ui/separator.tsx +7 -11
  175. package/src/shadcnui/ui/sheet.tsx +30 -55
  176. package/src/shadcnui/ui/sidebar.tsx +141 -189
  177. package/src/shadcnui/ui/skeleton.tsx +3 -9
  178. package/src/shadcnui/ui/slider.tsx +11 -23
  179. package/src/shadcnui/ui/switch.tsx +8 -8
  180. package/src/shadcnui/ui/tabs.tsx +14 -21
  181. package/src/shadcnui/ui/textarea.tsx +5 -5
  182. package/src/shadcnui/ui/toggle.tsx +8 -14
  183. package/src/shadcnui/ui/tooltip.tsx +11 -23
  184. package/src/testing/providers/MockJsonApiProvider.tsx +1 -5
  185. package/src/testing/utils/renderWithProviders.tsx +6 -10
  186. package/dist/BlockNoteEditor-SZWO3MDO.mjs.map +0 -1
  187. package/dist/chunk-53IPQJVH.js.map +0 -1
  188. package/dist/chunk-E6PQQTWF.js.map +0 -1
  189. package/dist/chunk-I7DFEJFF.mjs.map +0 -1
  190. package/dist/chunk-P7R2DPD6.mjs.map +0 -1
@@ -86,9 +86,7 @@ export function OAuthClientDetail({
86
86
  }
87
87
  }, [onRegenerateSecret]);
88
88
 
89
- const createdDate = client.createdAt
90
- ? format(new Date(client.createdAt), "MMMM d, yyyy")
91
- : "Unknown";
89
+ const createdDate = client.createdAt ? format(new Date(client.createdAt), "MMMM d, yyyy") : "Unknown";
92
90
 
93
91
  return (
94
92
  <>
@@ -97,17 +95,13 @@ export function OAuthClientDetail({
97
95
  <div className="flex items-start justify-between">
98
96
  <div>
99
97
  <CardTitle className="text-2xl">{client.name}</CardTitle>
100
- {client.description && (
101
- <CardDescription className="mt-1">{client.description}</CardDescription>
102
- )}
98
+ {client.description && <CardDescription className="mt-1">{client.description}</CardDescription>}
103
99
  </div>
104
100
  <div className="flex items-center gap-2">
105
101
  <Badge variant={client.isActive ? "default" : "secondary"}>
106
102
  {client.isActive ? "Active" : "Inactive"}
107
103
  </Badge>
108
- <Badge variant="outline">
109
- {client.isConfidential ? "Confidential" : "Public"}
110
- </Badge>
104
+ <Badge variant="outline">{client.isConfidential ? "Confidential" : "Public"}</Badge>
111
105
  </div>
112
106
  </div>
113
107
  </CardHeader>
@@ -209,11 +203,7 @@ export function OAuthClientDetail({
209
203
  </Button>
210
204
  )}
211
205
  {onDelete && (
212
- <Button
213
- variant="destructive"
214
- onClick={() => setShowDeleteConfirm(true)}
215
- disabled={isLoading}
216
- >
206
+ <Button variant="destructive" onClick={() => setShowDeleteConfirm(true)} disabled={isLoading}>
217
207
  <Trash2 className="h-4 w-4 mr-2" />
218
208
  Delete
219
209
  </Button>
@@ -228,8 +218,7 @@ export function OAuthClientDetail({
228
218
  <AlertDialogHeader>
229
219
  <AlertDialogTitle>Delete OAuth Application?</AlertDialogTitle>
230
220
  <AlertDialogDescription>
231
- This will permanently delete "{client.name}" and revoke all access tokens.
232
- This action cannot be undone.
221
+ This will permanently delete "{client.name}" and revoke all access tokens. This action cannot be undone.
233
222
  </AlertDialogDescription>
234
223
  </AlertDialogHeader>
235
224
  <AlertDialogFooter>
@@ -251,9 +240,8 @@ export function OAuthClientDetail({
251
240
  <AlertDialogHeader>
252
241
  <AlertDialogTitle>Regenerate Client Secret?</AlertDialogTitle>
253
242
  <AlertDialogDescription>
254
- This will generate a new client secret and invalidate the old one.
255
- All existing tokens will be revoked. You will need to update your application
256
- with the new secret.
243
+ This will generate a new client secret and invalidate the old one. All existing tokens will be revoked.
244
+ You will need to update your application with the new secret.
257
245
  </AlertDialogDescription>
258
246
  </AlertDialogHeader>
259
247
  <AlertDialogFooter>
@@ -47,12 +47,7 @@ interface FormErrors {
47
47
  /**
48
48
  * Form for creating or editing an OAuth client
49
49
  */
50
- export function OAuthClientForm({
51
- client,
52
- onSubmit,
53
- onCancel,
54
- isLoading = false,
55
- }: OAuthClientFormProps) {
50
+ export function OAuthClientForm({ client, onSubmit, onCancel, isLoading = false }: OAuthClientFormProps) {
56
51
  const isEditMode = !!client;
57
52
 
58
53
  const [formState, setFormState] = useState<FormState>({
@@ -102,7 +97,7 @@ export function OAuthClientForm({
102
97
 
103
98
  await onSubmit(data);
104
99
  },
105
- [formState, validate, onSubmit]
100
+ [formState, validate, onSubmit],
106
101
  );
107
102
 
108
103
  return (
@@ -111,9 +106,7 @@ export function OAuthClientForm({
111
106
  <CardHeader>
112
107
  <CardTitle>{isEditMode ? "Edit Application" : "Create OAuth Application"}</CardTitle>
113
108
  <CardDescription>
114
- {isEditMode
115
- ? "Update your OAuth application settings."
116
- : "Register a new application to access the API."}
109
+ {isEditMode ? "Update your OAuth application settings." : "Register a new application to access the API."}
117
110
  </CardDescription>
118
111
  </CardHeader>
119
112
  <CardContent className="space-y-6">
@@ -192,9 +185,7 @@ export function OAuthClientForm({
192
185
  </div>
193
186
  </RadioGroup>
194
187
  {isEditMode && (
195
- <p className="text-sm text-muted-foreground">
196
- Client type cannot be changed after creation.
197
- </p>
188
+ <p className="text-sm text-muted-foreground">Client type cannot be changed after creation.</p>
198
189
  )}
199
190
  </div>
200
191
  </CardContent>
@@ -41,12 +41,7 @@ export interface OAuthClientSecretDisplayProps {
41
41
  * />
42
42
  * ```
43
43
  */
44
- export function OAuthClientSecretDisplay({
45
- secret,
46
- onDismiss,
47
- open,
48
- clientName,
49
- }: OAuthClientSecretDisplayProps) {
44
+ export function OAuthClientSecretDisplay({ secret, onDismiss, open, clientName }: OAuthClientSecretDisplayProps) {
50
45
  const [copied, setCopied] = useState(false);
51
46
 
52
47
  const handleCopy = useCallback(async () => {
@@ -90,12 +85,7 @@ export function OAuthClientSecretDisplay({
90
85
 
91
86
  <div className="flex items-center space-x-2">
92
87
  <div className="flex-1">
93
- <Input
94
- value={secret}
95
- readOnly
96
- className="font-mono text-sm"
97
- onClick={(e) => e.currentTarget.select()}
98
- />
88
+ <Input value={secret} readOnly className="font-mono text-sm" onClick={(e) => e.currentTarget.select()} />
99
89
  </div>
100
90
  <Button
101
91
  type="button"
@@ -104,17 +94,11 @@ export function OAuthClientSecretDisplay({
104
94
  onClick={handleCopy}
105
95
  title={copied ? "Copied!" : "Copy to clipboard"}
106
96
  >
107
- {copied ? (
108
- <Check className="h-4 w-4 text-green-600" />
109
- ) : (
110
- <Copy className="h-4 w-4" />
111
- )}
97
+ {copied ? <Check className="h-4 w-4 text-green-600" /> : <Copy className="h-4 w-4" />}
112
98
  </Button>
113
99
  </div>
114
100
 
115
- {copied && (
116
- <p className="text-sm text-green-600 text-center">Copied to clipboard!</p>
117
- )}
101
+ {copied && <p className="text-sm text-green-600 text-center">Copied to clipboard!</p>}
118
102
 
119
103
  <DialogFooter className="mt-4">
120
104
  <Button onClick={handleDismiss} className="w-full">
@@ -79,7 +79,7 @@ export function OAuthRedirectUriInput({
79
79
  // Keep at least one empty input
80
80
  onChange(newUris.length > 0 ? newUris : [""]);
81
81
  },
82
- [value, onChange]
82
+ [value, onChange],
83
83
  );
84
84
 
85
85
  const handleChange = useCallback(
@@ -88,15 +88,15 @@ export function OAuthRedirectUriInput({
88
88
  newUris[index] = newValue;
89
89
  onChange(newUris);
90
90
  },
91
- [value, onChange]
91
+ [value, onChange],
92
92
  );
93
93
 
94
94
  return (
95
95
  <div className="space-y-2">
96
96
  <Label>{label} *</Label>
97
97
  <p className="text-sm text-muted-foreground">
98
- Enter the URIs where users will be redirected after authorization.
99
- Use https:// for production, or custom schemes for mobile apps.
98
+ Enter the URIs where users will be redirected after authorization. Use https:// for production, or custom
99
+ schemes for mobile apps.
100
100
  </p>
101
101
 
102
102
  <div className="space-y-2">
@@ -134,14 +134,7 @@ export function OAuthRedirectUriInput({
134
134
  })}
135
135
  </div>
136
136
 
137
- <Button
138
- type="button"
139
- variant="outline"
140
- size="sm"
141
- onClick={handleAdd}
142
- disabled={disabled}
143
- className="mt-2"
144
- >
137
+ <Button type="button" variant="outline" size="sm" onClick={handleAdd} disabled={disabled} className="mt-2">
145
138
  <Plus className="h-4 w-4 mr-2" />
146
139
  Add Redirect URI
147
140
  </Button>
@@ -49,28 +49,29 @@ export function OAuthScopeSelector({
49
49
  onChange(value.filter((s) => s !== scope));
50
50
  }
51
51
  },
52
- [value, onChange]
52
+ [value, onChange],
53
53
  );
54
54
 
55
55
  // Group scopes by category (before the colon)
56
- const groupedScopes = availableScopes.reduce((acc, scope) => {
57
- const [category] = scope.scope.split(":");
58
- const groupName = category === scope.scope ? "General" : category;
56
+ const groupedScopes = availableScopes.reduce(
57
+ (acc, scope) => {
58
+ const [category] = scope.scope.split(":");
59
+ const groupName = category === scope.scope ? "General" : category;
59
60
 
60
- if (!acc[groupName]) {
61
- acc[groupName] = [];
62
- }
63
- acc[groupName].push(scope);
64
- return acc;
65
- }, {} as Record<string, OAuthScopeInfo[]>);
61
+ if (!acc[groupName]) {
62
+ acc[groupName] = [];
63
+ }
64
+ acc[groupName].push(scope);
65
+ return acc;
66
+ },
67
+ {} as Record<string, OAuthScopeInfo[]>,
68
+ );
66
69
 
67
70
  return (
68
71
  <div className="space-y-4">
69
72
  <div>
70
73
  <Label>{label} *</Label>
71
- <p className="text-sm text-muted-foreground">
72
- Select the permissions your application needs.
73
- </p>
74
+ <p className="text-sm text-muted-foreground">Select the permissions your application needs.</p>
74
75
  </div>
75
76
 
76
77
  <div className="space-y-4">
@@ -92,20 +93,13 @@ export function OAuthScopeSelector({
92
93
  <Checkbox
93
94
  id={`scope-${scopeInfo.scope}`}
94
95
  checked={isChecked}
95
- onCheckedChange={(checked) =>
96
- handleToggle(scopeInfo.scope, checked === true)
97
- }
96
+ onCheckedChange={(checked) => handleToggle(scopeInfo.scope, checked === true)}
98
97
  disabled={disabled}
99
98
  />
100
99
  <div className="flex-1">
101
- <Label
102
- htmlFor={`scope-${scopeInfo.scope}`}
103
- className="text-sm font-medium cursor-pointer"
104
- >
100
+ <Label htmlFor={`scope-${scopeInfo.scope}`} className="text-sm font-medium cursor-pointer">
105
101
  {scopeInfo.name}
106
- {isAdmin && (
107
- <span className="ml-2 text-xs text-destructive">(Dangerous)</span>
108
- )}
102
+ {isAdmin && <span className="ml-2 text-xs text-destructive">(Dangerous)</span>}
109
103
  </Label>
110
104
  <p className="text-xs text-muted-foreground">{scopeInfo.description}</p>
111
105
  </div>
@@ -14,26 +14,13 @@ export interface OAuthConsentActionsProps {
14
14
  /**
15
15
  * Action buttons for OAuth consent screen
16
16
  */
17
- export function OAuthConsentActions({
18
- onApprove,
19
- onDeny,
20
- isLoading = false,
21
- }: OAuthConsentActionsProps) {
17
+ export function OAuthConsentActions({ onApprove, onDeny, isLoading = false }: OAuthConsentActionsProps) {
22
18
  return (
23
19
  <div className="flex flex-col sm:flex-row gap-3">
24
- <Button
25
- variant="outline"
26
- onClick={onDeny}
27
- disabled={isLoading}
28
- className="flex-1"
29
- >
20
+ <Button variant="outline" onClick={onDeny} disabled={isLoading} className="flex-1">
30
21
  Deny
31
22
  </Button>
32
- <Button
33
- onClick={onApprove}
34
- disabled={isLoading}
35
- className="flex-1"
36
- >
23
+ <Button onClick={onApprove} disabled={isLoading} className="flex-1">
37
24
  {isLoading ? "Authorizing..." : "Authorize"}
38
25
  </Button>
39
26
  </div>
@@ -16,21 +16,13 @@ export interface OAuthConsentHeaderProps {
16
16
  * Header component for OAuth consent screen
17
17
  * Shows platform logo and requesting app information
18
18
  */
19
- export function OAuthConsentHeader({
20
- client,
21
- logoUrl,
22
- appName = "Only35",
23
- }: OAuthConsentHeaderProps) {
19
+ export function OAuthConsentHeader({ client, logoUrl, appName = "Only35" }: OAuthConsentHeaderProps) {
24
20
  return (
25
21
  <div className="text-center space-y-4">
26
22
  {/* Platform Logo */}
27
23
  <div className="flex justify-center">
28
24
  {logoUrl ? (
29
- <img
30
- src={logoUrl}
31
- alt={appName}
32
- className="h-12 w-auto"
33
- />
25
+ <img src={logoUrl} alt={appName} className="h-12 w-auto" />
34
26
  ) : (
35
27
  <div className="h-12 w-12 rounded-full bg-primary flex items-center justify-center">
36
28
  <Shield className="h-6 w-6 text-primary-foreground" />
@@ -42,8 +34,7 @@ export function OAuthConsentHeader({
42
34
  <div className="space-y-2">
43
35
  <h1 className="text-2xl font-bold">Authorize {client.name}</h1>
44
36
  <p className="text-muted-foreground">
45
- <span className="font-medium text-foreground">{client.name}</span>
46
- {" "}wants to access your {appName} account
37
+ <span className="font-medium text-foreground">{client.name}</span> wants to access your {appName} account
47
38
  </p>
48
39
  </div>
49
40
  </div>
@@ -1,14 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { ExternalLink, AlertTriangle, Loader2 } from "lucide-react";
4
- import {
5
- Card,
6
- CardContent,
7
- CardFooter,
8
- Separator,
9
- Alert,
10
- AlertDescription,
11
- } from "../../../../shadcnui";
4
+ import { Card, CardContent, CardFooter, Separator, Alert, AlertDescription } from "../../../../shadcnui";
12
5
  import { OAuthConsentHeader } from "./OAuthConsentHeader";
13
6
  import { OAuthScopeList } from "./OAuthScopeList";
14
7
  import { OAuthConsentActions } from "./OAuthConsentActions";
@@ -92,11 +85,7 @@ export function OAuthConsentScreen({
92
85
  <Card className="w-full max-w-md">
93
86
  <CardContent className="pt-6 space-y-6">
94
87
  {/* Header */}
95
- <OAuthConsentHeader
96
- client={client}
97
- logoUrl={logoUrl}
98
- appName={appName}
99
- />
88
+ <OAuthConsentHeader client={client} logoUrl={logoUrl} appName={appName} />
100
89
 
101
90
  <Separator />
102
91
 
@@ -115,11 +104,7 @@ export function OAuthConsentScreen({
115
104
  </div>
116
105
 
117
106
  {/* Actions */}
118
- <OAuthConsentActions
119
- onApprove={approve}
120
- onDeny={deny}
121
- isLoading={isSubmitting}
122
- />
107
+ <OAuthConsentActions onApprove={approve} onDeny={deny} isLoading={isSubmitting} />
123
108
  </CardContent>
124
109
 
125
110
  {/* Footer */}
@@ -128,8 +113,8 @@ export function OAuthConsentScreen({
128
113
  By authorizing, you agree to the app's{" "}
129
114
  <a href={termsUrl} className="underline hover:text-foreground" target="_blank" rel="noopener">
130
115
  Terms of Service
131
- </a>
132
- {" "}and{" "}
116
+ </a>{" "}
117
+ and{" "}
133
118
  <a href={privacyUrl} className="underline hover:text-foreground" target="_blank" rel="noopener">
134
119
  Privacy Policy
135
120
  </a>
@@ -1,16 +1,6 @@
1
1
  "use client";
2
2
 
3
- import {
4
- Eye,
5
- Pencil,
6
- Image,
7
- Upload,
8
- Film,
9
- FolderPlus,
10
- User,
11
- Shield,
12
- LucideIcon,
13
- } from "lucide-react";
3
+ import { Eye, Pencil, Image, Upload, Film, FolderPlus, User, Shield, LucideIcon } from "lucide-react";
14
4
  import { OAuthScopeInfo } from "../../interfaces/oauth.interface";
15
5
 
16
6
  export interface OAuthScopeListProps {
@@ -48,15 +38,10 @@ export function OAuthScopeList({ scopes }: OAuthScopeListProps) {
48
38
  const IconComponent = scope.icon ? SCOPE_ICONS[scope.icon] : Eye;
49
39
 
50
40
  return (
51
- <li
52
- key={scope.scope}
53
- className="flex items-start gap-3 p-3 rounded-lg bg-muted/50"
54
- >
41
+ <li key={scope.scope} className="flex items-start gap-3 p-3 rounded-lg bg-muted/50">
55
42
  <div className="flex-shrink-0 mt-0.5">
56
43
  <div className="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center">
57
- {IconComponent && (
58
- <IconComponent className="h-4 w-4 text-primary" />
59
- )}
44
+ {IconComponent && <IconComponent className="h-4 w-4 text-primary" />}
60
45
  </div>
61
46
  </div>
62
47
  <div className="flex-1">
@@ -18,10 +18,10 @@ const OnboardingContext = createContext<OnboardingContextValue | null>(null);
18
18
  export function OnboardingProvider({
19
19
  children,
20
20
  tours = [],
21
- tourPaths = {},
21
+ tourPaths: _tourPaths = {},
22
22
  labels = DEFAULT_ONBOARDING_LABELS,
23
23
  renderCard,
24
- zIndex = 9999,
24
+ zIndex: _zIndex = 9999,
25
25
  }: OnboardingProviderProps) {
26
26
  const [isTourActive, setIsTourActive] = useState(false);
27
27
  const [activeTourId, setActiveTourId] = useState<string | null>(null);
@@ -35,7 +35,7 @@ export function OnboardingProvider({
35
35
  rootsRef.current.forEach((root) => {
36
36
  try {
37
37
  root.unmount();
38
- } catch (e) {
38
+ } catch (_e) {
39
39
  // Root may already be unmounted
40
40
  }
41
41
  });
@@ -2,13 +2,7 @@
2
2
 
3
3
  import { useTranslations } from "next-intl";
4
4
  import { FormFieldWrapper } from "../../../../components/forms";
5
- import {
6
- Checkbox,
7
- FieldLabel,
8
- Tooltip,
9
- TooltipContent,
10
- TooltipTrigger,
11
- } from "../../../../shadcnui";
5
+ import { Checkbox, FieldLabel, Tooltip, TooltipContent, TooltipTrigger } from "../../../../shadcnui";
12
6
  import { UserInterface } from "../../../user";
13
7
  import { useCurrentUserContext } from "../../../user/contexts";
14
8
  import { RoleInterface } from "../../data";
@@ -8,7 +8,7 @@ export function UserContainer() {
8
8
  const { user } = useUserContext();
9
9
  if (!user) return null;
10
10
 
11
- const t = useTranslations();
11
+ const _t = useTranslations();
12
12
 
13
13
  return (
14
14
  <div className="flex w-full gap-x-4">
@@ -26,7 +26,7 @@ export function UserDetails({ user }: UserDetailsProps) {
26
26
  roles = (
27
27
  <div className="mb-4 w-full">
28
28
  <div className="flex flex-wrap gap-2">
29
- {user.roles.map((role: RoleInterface, index: number) => (
29
+ {user.roles.map((role: RoleInterface, _index: number) => (
30
30
  <Link key={role.id} href={generateUrl({ page: Modules.Role, id: role.id })}>
31
31
  <Badge className="mr-2" variant={`default`}>
32
32
  {t(`role.roles`, { role: role.id.replaceAll(`-`, ``) })}
@@ -20,7 +20,7 @@ function UserDeleterInternal({ user, onDeleted, companyId }: UserDeleterProps) {
20
20
  const { currentUser, company } = useCurrentUserContext<UserInterface>();
21
21
  const generateUrl = usePageUrlGenerator();
22
22
  const router = useI18nRouter();
23
- const t = useTranslations();
23
+ const _t = useTranslations();
24
24
 
25
25
  let cId;
26
26
  if (currentUser?.roles.find((role) => role.id === getRoleId().Administrator) && companyId) {
@@ -106,7 +106,7 @@ function UserEditorInternal({ user, propagateChanges, adminCreated, trigger, onR
106
106
  errorToast({ title: t(`user.errors.email_exists`), error: "" });
107
107
  return;
108
108
  }
109
- } catch (error) {
109
+ } catch (_error) {
110
110
  // User does not exist, proceed
111
111
  }
112
112
  }
@@ -1,16 +1,12 @@
1
1
  "use client";
2
2
 
3
+ import { useTranslations } from "next-intl";
3
4
  import { useCallback, useEffect, useRef, useState } from "react";
4
5
  import { useWatch } from "react-hook-form";
5
6
  import { FormFieldWrapper } from "../../../../components/forms";
6
7
  import { Modules } from "../../../../core";
7
8
  import { DataListRetriever, useDataListRetriever, useDebounce } from "../../../../hooks";
8
- import {
9
- Avatar,
10
- AvatarFallback,
11
- AvatarImage,
12
- MultiSelect,
13
- } from "../../../../shadcnui";
9
+ import { Avatar, AvatarFallback, AvatarImage, MultiSelect } from "../../../../shadcnui";
14
10
  import { useCurrentUserContext } from "../../contexts";
15
11
  import { UserInterface } from "../../data";
16
12
  import { UserService } from "../../data/user.service";
@@ -59,10 +55,11 @@ export function UserMultiSelect({
59
55
  maxCount = 3,
60
56
  isRequired = false,
61
57
  }: UserMultiSelectProps) {
58
+ const t = useTranslations();
62
59
  const { company } = useCurrentUserContext<UserInterface>();
63
60
 
64
61
  const searchTermRef = useRef<string>("");
65
- const [searchTerm, setSearchTerm] = useState<string>("");
62
+ const [searchTerm, _setSearchTerm] = useState<string>("");
66
63
  const [isSearching, setIsSearching] = useState<boolean>(false);
67
64
  const [userOptions, setUserOptions] = useState<any[]>([]);
68
65
 
@@ -194,6 +191,9 @@ export function UserMultiSelect({
194
191
  placeholder={placeholder}
195
192
  maxCount={maxCount}
196
193
  animation={0}
194
+ loading={isSearching}
195
+ loadingText={t("ui.search.button")}
196
+ emptyText={t("ui.search.no_results", { type: t("entities.users", { count: 2 }) })}
197
197
  />
198
198
  )}
199
199
  </FormFieldWrapper>
@@ -28,11 +28,11 @@ export function UserListInAdd({ data, existingUsers, setSelectedUser, setLevelOp
28
28
  <CommandItem
29
29
  className="cursor-pointer hover:bg-muted data-selected:hover:bg-muted bg-transparent data-selected:bg-transparent"
30
30
  key={user.id}
31
- onClick={(e) => {
31
+ onClick={(_e) => {
32
32
  setSelectedUser(user);
33
33
  setLevelOpen?.(true);
34
34
  }}
35
- onSelect={(e) => {
35
+ onSelect={(_e) => {
36
36
  setSelectedUser(user);
37
37
  setLevelOpen?.(true);
38
38
  }}
@@ -16,7 +16,13 @@ type UsersListProps = {
16
16
  restrictToJoinRequests?: boolean;
17
17
  };
18
18
 
19
- export function UsersList({ data, optionComponents, removeFunction, hideOptions, showRelevance }: UsersListProps) {
19
+ export function UsersList({
20
+ data,
21
+ optionComponents: _optionComponents,
22
+ removeFunction: _removeFunction,
23
+ hideOptions: _hideOptions,
24
+ showRelevance: _showRelevance,
25
+ }: UsersListProps) {
20
26
  const t = useTranslations();
21
27
 
22
28
  return (