@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.
- package/dist/{BlockNoteEditor-4MDHRUS2.js → BlockNoteEditor-3S2B36O3.js} +15 -15
- package/dist/{BlockNoteEditor-4MDHRUS2.js.map → BlockNoteEditor-3S2B36O3.js.map} +1 -1
- package/dist/{BlockNoteEditor-SZWO3MDO.mjs → BlockNoteEditor-WQUJTVJL.mjs} +5 -5
- package/dist/BlockNoteEditor-WQUJTVJL.mjs.map +1 -0
- package/dist/billing/index.d.mts +15 -5
- package/dist/billing/index.d.ts +15 -5
- package/dist/billing/index.js +750 -520
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +665 -435
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-53IPQJVH.js → chunk-3EZX4G2E.js} +147 -23
- package/dist/chunk-3EZX4G2E.js.map +1 -0
- package/dist/{chunk-I7DFEJFF.mjs → chunk-4PHADEKA.mjs} +738 -1418
- package/dist/chunk-4PHADEKA.mjs.map +1 -0
- package/dist/{chunk-E6PQQTWF.js → chunk-T2JCZYWK.js} +999 -1679
- package/dist/chunk-T2JCZYWK.js.map +1 -0
- package/dist/{chunk-P7R2DPD6.mjs → chunk-TQ5GRRTM.mjs} +125 -1
- package/dist/chunk-TQ5GRRTM.mjs.map +1 -0
- package/dist/client/index.js +3 -3
- package/dist/client/index.mjs +2 -2
- package/dist/components/index.d.mts +23 -8
- package/dist/components/index.d.ts +23 -8
- package/dist/components/index.js +3 -3
- package/dist/components/index.mjs +2 -2
- package/dist/contexts/index.d.mts +1 -1
- package/dist/contexts/index.d.ts +1 -1
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +47 -3
- package/dist/core/index.d.ts +47 -3
- package/dist/core/index.js +8 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +7 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/{stripe-subscription.interface-DK7BJaNd.d.ts → stripe-promotion-code.interface-BcJty0rv.d.ts} +18 -1
- package/dist/{stripe-subscription.interface-C8uhCYIZ.d.mts → stripe-promotion-code.interface-Dnm2DJKQ.d.mts} +18 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/billing/index.ts +1 -0
- package/src/client/context/JsonApiProvider.tsx +1 -5
- package/src/client/hooks/__tests__/useJsonApiGet.test.tsx +9 -9
- package/src/client/hooks/__tests__/useJsonApiMutation.test.tsx +11 -11
- package/src/client/hooks/__tests__/useRehydration.test.ts +13 -34
- package/src/components/editors/BlockNoteEditor.tsx +2 -2
- package/src/components/forms/CommonEditorTrigger.tsx +1 -1
- package/src/components/forms/FormCheckbox.tsx +2 -12
- package/src/components/forms/FormDate.tsx +1 -6
- package/src/components/forms/FormInput.tsx +1 -1
- package/src/components/forms/FormPassword.tsx +1 -7
- package/src/components/forms/FormSelect.tsx +2 -8
- package/src/components/forms/FormSlider.tsx +1 -5
- package/src/components/forms/FormSwitch.tsx +1 -5
- package/src/components/forms/GdprConsentCheckbox.tsx +2 -8
- package/src/components/forms/PasswordInput.tsx +28 -26
- package/src/components/forms/__tests__/FormCheckbox.test.tsx +16 -18
- package/src/components/forms/__tests__/FormDate.test.tsx +14 -30
- package/src/components/forms/__tests__/FormInput.test.tsx +21 -37
- package/src/components/forms/__tests__/FormSelect.test.tsx +15 -21
- package/src/components/tables/ContentListTable.tsx +1 -1
- package/src/components/tables/__tests__/ContentListTable.test.tsx +17 -89
- package/src/components/tables/cells/cell.component.tsx +1 -1
- package/src/contexts/HeaderChildrenContext.tsx +3 -1
- package/src/core/endpoint/__tests__/EndpointCreator.test.ts +2 -7
- package/src/core/factories/__tests__/JsonApiDataFactory.test.ts +3 -3
- package/src/core/factories/__tests__/RehydrationFactory.test.ts +4 -6
- package/src/core/index.ts +1 -0
- package/src/core/registry/ModuleRegistry.ts +1 -0
- package/src/core/registry/__tests__/DataClassRegistry.test.ts +5 -15
- package/src/core/registry/__tests__/ModuleRegistrar.test.ts +5 -15
- package/src/features/auth/components/GdprConsentSection.tsx +1 -6
- package/src/features/auth/components/details/LandingComponent.tsx +6 -1
- package/src/features/auth/components/forms/AcceptInvitation.tsx +1 -1
- package/src/features/auth/components/forms/ResetPassword.tsx +1 -1
- package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +13 -18
- package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +12 -17
- package/src/features/billing/components/modals/BillingDetailModal.tsx +2 -13
- package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +8 -1
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +2 -13
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +2 -12
- package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +6 -1
- package/src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts +1 -0
- package/src/features/billing/stripe-price/components/lists/PricesList.tsx +13 -5
- package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +5 -5
- package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +108 -0
- package/src/features/billing/stripe-promotion-code/components/index.ts +1 -0
- package/src/features/billing/stripe-promotion-code/data/index.ts +3 -0
- package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.interface.ts +14 -0
- package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.service.ts +64 -0
- package/src/features/billing/stripe-promotion-code/data/stripe-promotion-code.ts +66 -0
- package/src/features/billing/stripe-promotion-code/index.ts +2 -0
- package/src/features/billing/stripe-promotion-code/stripe-promotion-code.module.ts +9 -0
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +1 -3
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +4 -1
- package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +1 -1
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +24 -4
- package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +9 -2
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +3 -1
- package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +7 -7
- package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +2 -10
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +3 -13
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +134 -23
- package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +2 -0
- package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +8 -0
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +93 -7
- package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +1 -1
- package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +1 -1
- package/src/features/company/components/details/CompanyDetails.tsx +2 -2
- package/src/features/company/components/forms/CompanyConfigurationSecurityForm.tsx +1 -1
- package/src/features/index.ts +1 -0
- package/src/features/notification/components/containers/NotificationsListContainer.tsx +1 -1
- package/src/features/notification/components/modals/NotificationModal.tsx +6 -2
- package/src/features/notification/contexts/NotificationContext.tsx +1 -3
- package/src/features/oauth/components/OAuthClientCard.tsx +15 -17
- package/src/features/oauth/components/OAuthClientDetail.tsx +7 -19
- package/src/features/oauth/components/OAuthClientForm.tsx +4 -13
- package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +4 -20
- package/src/features/oauth/components/OAuthRedirectUriInput.tsx +5 -12
- package/src/features/oauth/components/OAuthScopeSelector.tsx +17 -23
- package/src/features/oauth/components/consent/OAuthConsentActions.tsx +3 -16
- package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +3 -12
- package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +5 -20
- package/src/features/oauth/components/consent/OAuthScopeList.tsx +3 -18
- package/src/features/onboarding/contexts/OnboardingContext.tsx +3 -3
- package/src/features/role/components/forms/FormRoles.tsx +1 -7
- package/src/features/user/components/containers/UserContainer.tsx +1 -1
- package/src/features/user/components/details/UserDetails.tsx +1 -1
- package/src/features/user/components/forms/UserDeleter.tsx +1 -1
- package/src/features/user/components/forms/UserEditor.tsx +1 -1
- package/src/features/user/components/forms/UserMultiSelect.tsx +7 -7
- package/src/features/user/components/lists/UserListInAdd.tsx +2 -2
- package/src/features/user/components/lists/UsersList.tsx +7 -1
- package/src/features/user/contexts/CurrentUserContext.tsx +36 -33
- package/src/hooks/__tests__/useDataListRetriever.test.ts +15 -21
- package/src/hooks/__tests__/useDebounce.test.ts +2 -7
- package/src/hooks/useCustomD3Graph.tsx +2 -2
- package/src/shadcnui/custom/multi-select.tsx +28 -2
- package/src/shadcnui/ui/accordion.tsx +21 -23
- package/src/shadcnui/ui/alert-dialog.tsx +45 -62
- package/src/shadcnui/ui/alert.tsx +25 -41
- package/src/shadcnui/ui/avatar.tsx +23 -36
- package/src/shadcnui/ui/badge.tsx +13 -11
- package/src/shadcnui/ui/breadcrumb.tsx +21 -55
- package/src/shadcnui/ui/button.tsx +17 -18
- package/src/shadcnui/ui/calendar.tsx +44 -93
- package/src/shadcnui/ui/carousel.tsx +72 -100
- package/src/shadcnui/ui/chart.tsx +102 -161
- package/src/shadcnui/ui/checkbox.tsx +8 -9
- package/src/shadcnui/ui/combobox.tsx +52 -83
- package/src/shadcnui/ui/command.tsx +43 -77
- package/src/shadcnui/ui/context-menu.tsx +47 -86
- package/src/shadcnui/ui/dialog.tsx +34 -60
- package/src/shadcnui/ui/drawer.tsx +32 -53
- package/src/shadcnui/ui/dropdown-menu.tsx +48 -65
- package/src/shadcnui/ui/field.tsx +39 -48
- package/src/shadcnui/ui/hover-card.tsx +9 -14
- package/src/shadcnui/ui/input-group.tsx +44 -55
- package/src/shadcnui/ui/input-otp.tsx +22 -26
- package/src/shadcnui/ui/input.tsx +6 -6
- package/src/shadcnui/ui/label.tsx +6 -6
- package/src/shadcnui/ui/navigation-menu.tsx +36 -60
- package/src/shadcnui/ui/popover.tsx +15 -38
- package/src/shadcnui/ui/progress.tsx +12 -29
- package/src/shadcnui/ui/radio-group.tsx +9 -15
- package/src/shadcnui/ui/resizable.tsx +14 -24
- package/src/shadcnui/ui/scroll-area.tsx +12 -27
- package/src/shadcnui/ui/select.tsx +41 -65
- package/src/shadcnui/ui/separator.tsx +7 -11
- package/src/shadcnui/ui/sheet.tsx +30 -55
- package/src/shadcnui/ui/sidebar.tsx +141 -189
- package/src/shadcnui/ui/skeleton.tsx +3 -9
- package/src/shadcnui/ui/slider.tsx +11 -23
- package/src/shadcnui/ui/switch.tsx +8 -8
- package/src/shadcnui/ui/tabs.tsx +14 -21
- package/src/shadcnui/ui/textarea.tsx +5 -5
- package/src/shadcnui/ui/toggle.tsx +8 -14
- package/src/shadcnui/ui/tooltip.tsx +11 -23
- package/src/testing/providers/MockJsonApiProvider.tsx +1 -5
- package/src/testing/utils/renderWithProviders.tsx +6 -10
- package/dist/BlockNoteEditor-SZWO3MDO.mjs.map +0 -1
- package/dist/chunk-53IPQJVH.js.map +0 -1
- package/dist/chunk-E6PQQTWF.js.map +0 -1
- package/dist/chunk-I7DFEJFF.mjs.map +0 -1
- 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
|
-
|
|
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
|
-
|
|
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(
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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 (
|
|
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";
|
|
@@ -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,
|
|
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
|
|
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 (
|
|
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,
|
|
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={(
|
|
31
|
+
onClick={(_e) => {
|
|
32
32
|
setSelectedUser(user);
|
|
33
33
|
setLevelOpen?.(true);
|
|
34
34
|
}}
|
|
35
|
-
onSelect={(
|
|
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({
|
|
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 (
|