@carlonicora/nextjs-jsonapi 1.36.0 → 1.37.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-N3J42SBY.js → BlockNoteEditor-74FHJO7E.js} +15 -15
- package/dist/{BlockNoteEditor-N3J42SBY.js.map → BlockNoteEditor-74FHJO7E.js.map} +1 -1
- package/dist/{BlockNoteEditor-KFUTQVUK.mjs → BlockNoteEditor-GTWR6CPI.mjs} +5 -5
- package/dist/BlockNoteEditor-GTWR6CPI.mjs.map +1 -0
- package/dist/billing/index.d.mts +3 -3
- package/dist/billing/index.d.ts +3 -3
- package/dist/billing/index.js +404 -402
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +81 -79
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-NNCTRU4O.js → chunk-53IPQJVH.js} +10 -19
- package/dist/chunk-53IPQJVH.js.map +1 -0
- package/dist/{chunk-YZV24UWN.mjs → chunk-P7R2DPD6.mjs} +10 -19
- package/dist/{chunk-YZV24UWN.mjs.map → chunk-P7R2DPD6.mjs.map} +1 -1
- package/dist/{chunk-S2RZBQP4.js → chunk-YVEK3SUS.js} +998 -1699
- package/dist/chunk-YVEK3SUS.js.map +1 -0
- package/dist/{chunk-DLJTN632.mjs → chunk-ZUUH4CQC.mjs} +737 -1438
- package/dist/chunk-ZUUH4CQC.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.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/index.mjs.map +1 -1
- package/package.json +2 -2
- 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/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 +7 -1
- 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-price/components/lists/PricesList.tsx +13 -5
- package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +5 -5
- 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 +4 -1
- 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 +1 -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 +5 -16
- 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/company/components/forms/CompanyDeleter.tsx +0 -23
- package/src/features/company/data/company.service.ts +9 -20
- 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-KFUTQVUK.mjs.map +0 -1
- package/dist/chunk-DLJTN632.mjs.map +0 -1
- package/dist/chunk-NNCTRU4O.js.map +0 -1
- package/dist/chunk-S2RZBQP4.js.map +0 -1
|
@@ -36,7 +36,7 @@ describe.skip("FormSelect", () => {
|
|
|
36
36
|
render(
|
|
37
37
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
38
38
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
39
|
-
</FormWrapper
|
|
39
|
+
</FormWrapper>,
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
|
@@ -46,7 +46,7 @@ describe.skip("FormSelect", () => {
|
|
|
46
46
|
render(
|
|
47
47
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
48
48
|
{(form) => <FormSelect form={form} id="status" name="Status" values={mockValues} />}
|
|
49
|
-
</FormWrapper
|
|
49
|
+
</FormWrapper>,
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
expect(screen.getByText("Status")).toBeInTheDocument();
|
|
@@ -56,10 +56,8 @@ describe.skip("FormSelect", () => {
|
|
|
56
56
|
it("should render placeholder", () => {
|
|
57
57
|
render(
|
|
58
58
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
59
|
-
{(form) =>
|
|
60
|
-
|
|
61
|
-
)}
|
|
62
|
-
</FormWrapper>
|
|
59
|
+
{(form) => <FormSelect form={form} id="status" values={mockValues} placeholder="Select an option" />}
|
|
60
|
+
</FormWrapper>,
|
|
63
61
|
);
|
|
64
62
|
|
|
65
63
|
expect(screen.getByText("Select an option")).toBeInTheDocument();
|
|
@@ -69,7 +67,7 @@ describe.skip("FormSelect", () => {
|
|
|
69
67
|
render(
|
|
70
68
|
<FormWrapper defaultValues={{ status: "option2" }}>
|
|
71
69
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
72
|
-
</FormWrapper
|
|
70
|
+
</FormWrapper>,
|
|
73
71
|
);
|
|
74
72
|
|
|
75
73
|
expect(screen.getByRole("combobox")).toHaveTextContent("Option 2");
|
|
@@ -81,10 +79,8 @@ describe.skip("FormSelect", () => {
|
|
|
81
79
|
// Just verify it renders without error with useRows
|
|
82
80
|
render(
|
|
83
81
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
84
|
-
{(form) =>
|
|
85
|
-
|
|
86
|
-
)}
|
|
87
|
-
</FormWrapper>
|
|
82
|
+
{(form) => <FormSelect form={form} id="status" name="Status" values={mockValues} useRows={true} />}
|
|
83
|
+
</FormWrapper>,
|
|
88
84
|
);
|
|
89
85
|
|
|
90
86
|
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
|
@@ -94,10 +90,8 @@ describe.skip("FormSelect", () => {
|
|
|
94
90
|
it("should render label with row layout styling when useRows is true", () => {
|
|
95
91
|
const { container } = render(
|
|
96
92
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
97
|
-
{(form) =>
|
|
98
|
-
|
|
99
|
-
)}
|
|
100
|
-
</FormWrapper>
|
|
93
|
+
{(form) => <FormSelect form={form} id="status" name="Status" values={mockValues} useRows={true} />}
|
|
94
|
+
</FormWrapper>,
|
|
101
95
|
);
|
|
102
96
|
|
|
103
97
|
// The label should have min-w-28 class when useRows is true
|
|
@@ -111,7 +105,7 @@ describe.skip("FormSelect", () => {
|
|
|
111
105
|
render(
|
|
112
106
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
113
107
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
114
|
-
</FormWrapper
|
|
108
|
+
</FormWrapper>,
|
|
115
109
|
);
|
|
116
110
|
|
|
117
111
|
const trigger = screen.getByRole("combobox");
|
|
@@ -124,7 +118,7 @@ describe.skip("FormSelect", () => {
|
|
|
124
118
|
render(
|
|
125
119
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
126
120
|
{(form) => <FormSelect form={form} id="status" values={[]} placeholder="Select" />}
|
|
127
|
-
</FormWrapper
|
|
121
|
+
</FormWrapper>,
|
|
128
122
|
);
|
|
129
123
|
|
|
130
124
|
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
|
@@ -134,7 +128,7 @@ describe.skip("FormSelect", () => {
|
|
|
134
128
|
render(
|
|
135
129
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
136
130
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
137
|
-
</FormWrapper
|
|
131
|
+
</FormWrapper>,
|
|
138
132
|
);
|
|
139
133
|
|
|
140
134
|
const combobox = screen.getByRole("combobox");
|
|
@@ -145,7 +139,7 @@ describe.skip("FormSelect", () => {
|
|
|
145
139
|
render(
|
|
146
140
|
<FormWrapper defaultValues={{ status: "option1" }}>
|
|
147
141
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
148
|
-
</FormWrapper
|
|
142
|
+
</FormWrapper>,
|
|
149
143
|
);
|
|
150
144
|
|
|
151
145
|
expect(screen.getByRole("combobox")).toHaveTextContent("Option 1");
|
|
@@ -155,7 +149,7 @@ describe.skip("FormSelect", () => {
|
|
|
155
149
|
render(
|
|
156
150
|
<FormWrapper defaultValues={{ status: "option3" }}>
|
|
157
151
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
158
|
-
</FormWrapper
|
|
152
|
+
</FormWrapper>,
|
|
159
153
|
);
|
|
160
154
|
|
|
161
155
|
expect(screen.getByRole("combobox")).toHaveTextContent("Option 3");
|
|
@@ -167,7 +161,7 @@ describe.skip("FormSelect", () => {
|
|
|
167
161
|
render(
|
|
168
162
|
<FormWrapper defaultValues={{ status: "" }}>
|
|
169
163
|
{(form) => <FormSelect form={form} id="status" values={mockValues} />}
|
|
170
|
-
</FormWrapper
|
|
164
|
+
</FormWrapper>,
|
|
171
165
|
);
|
|
172
166
|
|
|
173
167
|
const combobox = screen.getByRole("combobox");
|
|
@@ -33,7 +33,7 @@ type ContentListTableProps = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export const ContentListTable = memo(function ContentListTable(props: ContentListTableProps) {
|
|
36
|
-
const { data, fields, checkedIds, toggleId, allowSearch, filters } = props;
|
|
36
|
+
const { data, fields, checkedIds, toggleId, allowSearch, filters: _filters } = props;
|
|
37
37
|
|
|
38
38
|
const { data: tableData, columns: tableColumns } = useTableGenerator(props.tableGeneratorType, {
|
|
39
39
|
data: data?.data ?? EMPTY_ARRAY,
|
|
@@ -75,13 +75,7 @@ describe("ContentListTable", () => {
|
|
|
75
75
|
],
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
render(
|
|
79
|
-
<ContentListTable
|
|
80
|
-
data={dataRetriever}
|
|
81
|
-
tableGeneratorType={mockModule as any}
|
|
82
|
-
fields={["id", "title"]}
|
|
83
|
-
/>
|
|
84
|
-
);
|
|
78
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
85
79
|
|
|
86
80
|
expect(screen.getByRole("table")).toBeInTheDocument();
|
|
87
81
|
});
|
|
@@ -97,7 +91,7 @@ describe("ContentListTable", () => {
|
|
|
97
91
|
tableGeneratorType={mockModule as any}
|
|
98
92
|
fields={["id", "title"]}
|
|
99
93
|
title="Articles"
|
|
100
|
-
|
|
94
|
+
/>,
|
|
101
95
|
);
|
|
102
96
|
|
|
103
97
|
expect(screen.getByText("Articles")).toBeInTheDocument();
|
|
@@ -108,13 +102,7 @@ describe("ContentListTable", () => {
|
|
|
108
102
|
data: [{ id: "1", title: "Article 1" }],
|
|
109
103
|
});
|
|
110
104
|
|
|
111
|
-
render(
|
|
112
|
-
<ContentListTable
|
|
113
|
-
data={dataRetriever}
|
|
114
|
-
tableGeneratorType={mockModule as any}
|
|
115
|
-
fields={["id", "title"]}
|
|
116
|
-
/>
|
|
117
|
-
);
|
|
105
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
118
106
|
|
|
119
107
|
expect(screen.getByText("ID")).toBeInTheDocument();
|
|
120
108
|
expect(screen.getByText("Title")).toBeInTheDocument();
|
|
@@ -128,13 +116,7 @@ describe("ContentListTable", () => {
|
|
|
128
116
|
],
|
|
129
117
|
});
|
|
130
118
|
|
|
131
|
-
render(
|
|
132
|
-
<ContentListTable
|
|
133
|
-
data={dataRetriever}
|
|
134
|
-
tableGeneratorType={mockModule as any}
|
|
135
|
-
fields={["id", "title"]}
|
|
136
|
-
/>
|
|
137
|
-
);
|
|
119
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
138
120
|
|
|
139
121
|
expect(screen.getByText("1")).toBeInTheDocument();
|
|
140
122
|
expect(screen.getByText("First Article")).toBeInTheDocument();
|
|
@@ -147,13 +129,7 @@ describe("ContentListTable", () => {
|
|
|
147
129
|
data: [],
|
|
148
130
|
});
|
|
149
131
|
|
|
150
|
-
render(
|
|
151
|
-
<ContentListTable
|
|
152
|
-
data={dataRetriever}
|
|
153
|
-
tableGeneratorType={mockModule as any}
|
|
154
|
-
fields={["id", "title"]}
|
|
155
|
-
/>
|
|
156
|
-
);
|
|
132
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
157
133
|
|
|
158
134
|
expect(screen.getByText("No results.")).toBeInTheDocument();
|
|
159
135
|
});
|
|
@@ -172,7 +148,7 @@ describe("ContentListTable", () => {
|
|
|
172
148
|
fields={["id", "title"]}
|
|
173
149
|
title="Articles"
|
|
174
150
|
allowSearch={true}
|
|
175
|
-
|
|
151
|
+
/>,
|
|
176
152
|
);
|
|
177
153
|
|
|
178
154
|
expect(screen.getByTestId("content-table-search")).toBeInTheDocument();
|
|
@@ -187,13 +163,7 @@ describe("ContentListTable", () => {
|
|
|
187
163
|
previous: vi.fn(),
|
|
188
164
|
});
|
|
189
165
|
|
|
190
|
-
render(
|
|
191
|
-
<ContentListTable
|
|
192
|
-
data={dataRetriever}
|
|
193
|
-
tableGeneratorType={mockModule as any}
|
|
194
|
-
fields={["id", "title"]}
|
|
195
|
-
/>
|
|
196
|
-
);
|
|
166
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
197
167
|
|
|
198
168
|
// Should have navigation buttons
|
|
199
169
|
const buttons = screen.getAllByRole("button");
|
|
@@ -207,13 +177,7 @@ describe("ContentListTable", () => {
|
|
|
207
177
|
previous: undefined,
|
|
208
178
|
});
|
|
209
179
|
|
|
210
|
-
render(
|
|
211
|
-
<ContentListTable
|
|
212
|
-
data={dataRetriever}
|
|
213
|
-
tableGeneratorType={mockModule as any}
|
|
214
|
-
fields={["id", "title"]}
|
|
215
|
-
/>
|
|
216
|
-
);
|
|
180
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
217
181
|
|
|
218
182
|
const buttons = screen.getAllByRole("button");
|
|
219
183
|
const previousButton = buttons[0];
|
|
@@ -227,13 +191,7 @@ describe("ContentListTable", () => {
|
|
|
227
191
|
previous: vi.fn(),
|
|
228
192
|
});
|
|
229
193
|
|
|
230
|
-
render(
|
|
231
|
-
<ContentListTable
|
|
232
|
-
data={dataRetriever}
|
|
233
|
-
tableGeneratorType={mockModule as any}
|
|
234
|
-
fields={["id", "title"]}
|
|
235
|
-
/>
|
|
236
|
-
);
|
|
194
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
237
195
|
|
|
238
196
|
const buttons = screen.getAllByRole("button");
|
|
239
197
|
const nextButton = buttons[buttons.length - 1];
|
|
@@ -249,13 +207,7 @@ describe("ContentListTable", () => {
|
|
|
249
207
|
next: nextFn,
|
|
250
208
|
});
|
|
251
209
|
|
|
252
|
-
render(
|
|
253
|
-
<ContentListTable
|
|
254
|
-
data={dataRetriever}
|
|
255
|
-
tableGeneratorType={mockModule as any}
|
|
256
|
-
fields={["id", "title"]}
|
|
257
|
-
/>
|
|
258
|
-
);
|
|
210
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
259
211
|
|
|
260
212
|
const buttons = screen.getAllByRole("button");
|
|
261
213
|
const nextButton = buttons[buttons.length - 1];
|
|
@@ -274,13 +226,7 @@ describe("ContentListTable", () => {
|
|
|
274
226
|
next: vi.fn(), // Need both to show footer
|
|
275
227
|
});
|
|
276
228
|
|
|
277
|
-
render(
|
|
278
|
-
<ContentListTable
|
|
279
|
-
data={dataRetriever}
|
|
280
|
-
tableGeneratorType={mockModule as any}
|
|
281
|
-
fields={["id", "title"]}
|
|
282
|
-
/>
|
|
283
|
-
);
|
|
229
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
284
230
|
|
|
285
231
|
const buttons = screen.getAllByRole("button");
|
|
286
232
|
const previousButton = buttons[0];
|
|
@@ -300,13 +246,7 @@ describe("ContentListTable", () => {
|
|
|
300
246
|
},
|
|
301
247
|
});
|
|
302
248
|
|
|
303
|
-
render(
|
|
304
|
-
<ContentListTable
|
|
305
|
-
data={dataRetriever}
|
|
306
|
-
tableGeneratorType={mockModule as any}
|
|
307
|
-
fields={["id", "title"]}
|
|
308
|
-
/>
|
|
309
|
-
);
|
|
249
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
310
250
|
|
|
311
251
|
expect(screen.getByText("1-25")).toBeInTheDocument();
|
|
312
252
|
});
|
|
@@ -325,7 +265,7 @@ describe("ContentListTable", () => {
|
|
|
325
265
|
fields={["id", "title"]}
|
|
326
266
|
title="Articles"
|
|
327
267
|
functions={<button data-testid="custom-function">Custom</button>}
|
|
328
|
-
|
|
268
|
+
/>,
|
|
329
269
|
);
|
|
330
270
|
|
|
331
271
|
expect(screen.getByTestId("custom-function")).toBeInTheDocument();
|
|
@@ -343,7 +283,7 @@ describe("ContentListTable", () => {
|
|
|
343
283
|
fields={["id", "title"]}
|
|
344
284
|
title="Articles"
|
|
345
285
|
filters={<div data-testid="custom-filter">Filter</div>}
|
|
346
|
-
|
|
286
|
+
/>,
|
|
347
287
|
);
|
|
348
288
|
|
|
349
289
|
expect(screen.getByTestId("custom-filter")).toBeInTheDocument();
|
|
@@ -362,7 +302,7 @@ describe("ContentListTable", () => {
|
|
|
362
302
|
tableGeneratorType={mockModule as any}
|
|
363
303
|
fields={["id", "title"]}
|
|
364
304
|
functions={<button>Action</button>}
|
|
365
|
-
|
|
305
|
+
/>,
|
|
366
306
|
);
|
|
367
307
|
|
|
368
308
|
// Footer should be present with buttons
|
|
@@ -376,13 +316,7 @@ describe("ContentListTable", () => {
|
|
|
376
316
|
next: vi.fn(),
|
|
377
317
|
});
|
|
378
318
|
|
|
379
|
-
render(
|
|
380
|
-
<ContentListTable
|
|
381
|
-
data={dataRetriever}
|
|
382
|
-
tableGeneratorType={mockModule as any}
|
|
383
|
-
fields={["id", "title"]}
|
|
384
|
-
/>
|
|
385
|
-
);
|
|
319
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
386
320
|
|
|
387
321
|
// Should have navigation buttons in footer
|
|
388
322
|
const buttons = screen.getAllByRole("button");
|
|
@@ -395,13 +329,7 @@ describe("ContentListTable", () => {
|
|
|
395
329
|
previous: vi.fn(),
|
|
396
330
|
});
|
|
397
331
|
|
|
398
|
-
render(
|
|
399
|
-
<ContentListTable
|
|
400
|
-
data={dataRetriever}
|
|
401
|
-
tableGeneratorType={mockModule as any}
|
|
402
|
-
fields={["id", "title"]}
|
|
403
|
-
/>
|
|
404
|
-
);
|
|
332
|
+
render(<ContentListTable data={dataRetriever} tableGeneratorType={mockModule as any} fields={["id", "title"]} />);
|
|
405
333
|
|
|
406
334
|
// Should have navigation buttons in footer
|
|
407
335
|
const buttons = screen.getAllByRole("button");
|
|
@@ -20,7 +20,9 @@ interface HeaderChildrenProviderProps {
|
|
|
20
20
|
* Wrap your layout with this provider and pass the content you want in the header.
|
|
21
21
|
*/
|
|
22
22
|
export function HeaderChildrenProvider({ children, content }: HeaderChildrenProviderProps) {
|
|
23
|
-
return
|
|
23
|
+
return (
|
|
24
|
+
<HeaderChildrenContext.Provider value={{ headerChildren: content }}>{children}</HeaderChildrenContext.Provider>
|
|
25
|
+
);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
/**
|
|
@@ -74,10 +74,7 @@ describe("EndpointCreator", () => {
|
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
it("should support full fluent chain", () => {
|
|
77
|
-
const creator = new EndpointCreator({ endpoint: "articles" })
|
|
78
|
-
.id("123")
|
|
79
|
-
.childEndpoint("comments")
|
|
80
|
-
.childId("456");
|
|
77
|
+
const creator = new EndpointCreator({ endpoint: "articles" }).id("123").childEndpoint("comments").childId("456");
|
|
81
78
|
expect(creator.generate()).toBe("articles/123/comments/456");
|
|
82
79
|
});
|
|
83
80
|
});
|
|
@@ -141,9 +138,7 @@ describe("EndpointCreator", () => {
|
|
|
141
138
|
{ type: "articles", fields: ["title", "body"] },
|
|
142
139
|
{ type: "authors", fields: ["name", "email"] },
|
|
143
140
|
]);
|
|
144
|
-
expect(creator.generate()).toBe(
|
|
145
|
-
"articles?fields[articles]=title,body&fields[authors]=name,email"
|
|
146
|
-
);
|
|
141
|
+
expect(creator.generate()).toBe("articles?fields[articles]=title,body&fields[authors]=name,email");
|
|
147
142
|
});
|
|
148
143
|
|
|
149
144
|
it("should handle empty selectors array", () => {
|
|
@@ -74,9 +74,9 @@ describe("JsonApiDataFactory", () => {
|
|
|
74
74
|
it("should throw for unregistered module", () => {
|
|
75
75
|
const unregisteredModule = { name: "unknown", model: MockDataClass };
|
|
76
76
|
|
|
77
|
-
expect(() =>
|
|
78
|
-
|
|
79
|
-
)
|
|
77
|
+
expect(() => JsonApiDataFactory.create(unregisteredModule as any, { data: "test" })).toThrow(
|
|
78
|
+
"Class not registered for key: unknown",
|
|
79
|
+
);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it("should handle empty data", () => {
|
|
@@ -72,9 +72,9 @@ describe("RehydrationFactory", () => {
|
|
|
72
72
|
included: [],
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
expect(() =>
|
|
76
|
-
|
|
77
|
-
)
|
|
75
|
+
expect(() => RehydrationFactory.rehydrate(unregisteredModule as any, hydratedData)).toThrow(
|
|
76
|
+
"Class not registered for key: unknown",
|
|
77
|
+
);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
it("should create a new instance for rehydration", () => {
|
|
@@ -128,9 +128,7 @@ describe("RehydrationFactory", () => {
|
|
|
128
128
|
const unregisteredModule = { name: "unknown", model: MockDataClass };
|
|
129
129
|
|
|
130
130
|
expect(() =>
|
|
131
|
-
RehydrationFactory.rehydrateList(unregisteredModule as any, [
|
|
132
|
-
{ jsonApi: {}, included: [] },
|
|
133
|
-
])
|
|
131
|
+
RehydrationFactory.rehydrateList(unregisteredModule as any, [{ jsonApi: {}, included: [] }]),
|
|
134
132
|
).toThrow("Class not registered for key: unknown");
|
|
135
133
|
});
|
|
136
134
|
|
|
@@ -67,9 +67,7 @@ describe("DataClassRegistry", () => {
|
|
|
67
67
|
|
|
68
68
|
it("should throw for unregistered class", () => {
|
|
69
69
|
const module = createMockModule({ name: "unknown" });
|
|
70
|
-
expect(() => DataClassRegistry.get(module)).toThrow(
|
|
71
|
-
"Class not registered for key: unknown"
|
|
72
|
-
);
|
|
70
|
+
expect(() => DataClassRegistry.get(module)).toThrow("Class not registered for key: unknown");
|
|
73
71
|
});
|
|
74
72
|
});
|
|
75
73
|
|
|
@@ -88,12 +86,8 @@ describe("DataClassRegistry", () => {
|
|
|
88
86
|
|
|
89
87
|
DataClassRegistry.bootstrap(modules as any);
|
|
90
88
|
|
|
91
|
-
expect(() =>
|
|
92
|
-
|
|
93
|
-
).not.toThrow();
|
|
94
|
-
expect(() =>
|
|
95
|
-
DataClassRegistry.get({ name: "users", model: MockArticle } as any)
|
|
96
|
-
).not.toThrow();
|
|
89
|
+
expect(() => DataClassRegistry.get({ name: "articles", model: MockArticle } as any)).not.toThrow();
|
|
90
|
+
expect(() => DataClassRegistry.get({ name: "users", model: MockArticle } as any)).not.toThrow();
|
|
97
91
|
});
|
|
98
92
|
|
|
99
93
|
it("should skip modules without model", () => {
|
|
@@ -110,12 +104,8 @@ describe("DataClassRegistry", () => {
|
|
|
110
104
|
|
|
111
105
|
DataClassRegistry.bootstrap(modules as any);
|
|
112
106
|
|
|
113
|
-
expect(() =>
|
|
114
|
-
|
|
115
|
-
).not.toThrow();
|
|
116
|
-
expect(() =>
|
|
117
|
-
DataClassRegistry.get({ name: "invalid", model: null } as any)
|
|
118
|
-
).toThrow();
|
|
107
|
+
expect(() => DataClassRegistry.get({ name: "articles", model: MockArticle } as any)).not.toThrow();
|
|
108
|
+
expect(() => DataClassRegistry.get({ name: "invalid", model: null } as any)).toThrow();
|
|
119
109
|
});
|
|
120
110
|
});
|
|
121
111
|
|
|
@@ -98,12 +98,8 @@ describe("ModuleRegistrar", () => {
|
|
|
98
98
|
ModuleRegistrar.bootstrap(MockModules);
|
|
99
99
|
|
|
100
100
|
// Should be able to get registered classes
|
|
101
|
-
expect(() =>
|
|
102
|
-
|
|
103
|
-
).not.toThrow();
|
|
104
|
-
expect(() =>
|
|
105
|
-
DataClassRegistry.get({ name: "articles", model: MockArticle } as any)
|
|
106
|
-
).not.toThrow();
|
|
101
|
+
expect(() => DataClassRegistry.get({ name: "users", model: MockUser } as any)).not.toThrow();
|
|
102
|
+
expect(() => DataClassRegistry.get({ name: "articles", model: MockArticle } as any)).not.toThrow();
|
|
107
103
|
});
|
|
108
104
|
|
|
109
105
|
it("should only bootstrap once", () => {
|
|
@@ -114,9 +110,7 @@ describe("ModuleRegistrar", () => {
|
|
|
114
110
|
ModuleRegistrar.bootstrap(MockModules);
|
|
115
111
|
|
|
116
112
|
// Registry should still be empty because second bootstrap was skipped
|
|
117
|
-
expect(() =>
|
|
118
|
-
DataClassRegistry.get({ name: "users", model: MockUser } as any)
|
|
119
|
-
).toThrow();
|
|
113
|
+
expect(() => DataClassRegistry.get({ name: "users", model: MockUser } as any)).toThrow();
|
|
120
114
|
});
|
|
121
115
|
|
|
122
116
|
it("should handle class without model property", () => {
|
|
@@ -141,9 +135,7 @@ describe("ModuleRegistrar", () => {
|
|
|
141
135
|
// Can bootstrap again after reset
|
|
142
136
|
ModuleRegistrar.bootstrap(MockModules);
|
|
143
137
|
|
|
144
|
-
expect(() =>
|
|
145
|
-
DataClassRegistry.get({ name: "users", model: MockUser } as any)
|
|
146
|
-
).not.toThrow();
|
|
138
|
+
expect(() => DataClassRegistry.get({ name: "users", model: MockUser } as any)).not.toThrow();
|
|
147
139
|
});
|
|
148
140
|
|
|
149
141
|
it("should clear the registry", () => {
|
|
@@ -151,9 +143,7 @@ describe("ModuleRegistrar", () => {
|
|
|
151
143
|
ModuleRegistrar.reset();
|
|
152
144
|
|
|
153
145
|
// Registry should be cleared
|
|
154
|
-
expect(() =>
|
|
155
|
-
DataClassRegistry.get({ name: "users", model: MockUser } as any)
|
|
156
|
-
).toThrow();
|
|
146
|
+
expect(() => DataClassRegistry.get({ name: "users", model: MockUser } as any)).toThrow();
|
|
157
147
|
});
|
|
158
148
|
});
|
|
159
149
|
});
|
|
@@ -33,12 +33,7 @@ export function GdprConsentSection<T extends FieldValues>({
|
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
35
|
<div className="space-y-4 py-4">
|
|
36
|
-
<GdprConsentCheckbox
|
|
37
|
-
form={form}
|
|
38
|
-
id={termsCheckboxId}
|
|
39
|
-
label={termsLabel}
|
|
40
|
-
required
|
|
41
|
-
/>
|
|
36
|
+
<GdprConsentCheckbox form={form} id={termsCheckboxId} label={termsLabel} required />
|
|
42
37
|
<GdprConsentCheckbox
|
|
43
38
|
form={form}
|
|
44
39
|
id={marketingCheckboxId}
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
4
|
import Image from "next/image";
|
|
5
5
|
import { getApiUrl } from "../../../../client/config";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isDiscordAuthEnabled,
|
|
8
|
+
isGoogleAuthEnabled,
|
|
9
|
+
isInternalAuthEnabled,
|
|
10
|
+
isRegistrationAllowed,
|
|
11
|
+
} from "../../../../login";
|
|
7
12
|
import { Button, CardDescription, CardFooter, CardHeader, CardTitle, Link } from "../../../../shadcnui";
|
|
8
13
|
import { useAuthContext } from "../../contexts";
|
|
9
14
|
import { AuthComponent } from "../../enums";
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Wallet, ChevronRight } from "lucide-react";
|
|
4
|
-
import {
|
|
5
|
-
Card,
|
|
6
|
-
CardContent,
|
|
7
|
-
CardHeader,
|
|
8
|
-
CardTitle,
|
|
9
|
-
Button,
|
|
10
|
-
Skeleton,
|
|
11
|
-
} from "../../../../shadcnui";
|
|
4
|
+
import { Card, CardContent, CardHeader, CardTitle, Button, Skeleton } from "../../../../shadcnui";
|
|
12
5
|
import { PaymentMethodInterface } from "../../stripe-customer";
|
|
13
6
|
|
|
14
7
|
type PaymentMethodSummaryCardProps = {
|
|
@@ -81,10 +74,16 @@ export function PaymentMethodSummaryCard({
|
|
|
81
74
|
{paymentMethods.length === 0 ? (
|
|
82
75
|
<div className="space-y-2">
|
|
83
76
|
<p className="text-xl font-bold text-muted-foreground">No payment method</p>
|
|
84
|
-
<p className="text-xs text-muted-foreground">
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
<p className="text-xs text-muted-foreground">Add a card to enable subscriptions</p>
|
|
78
|
+
<Button
|
|
79
|
+
variant="outline"
|
|
80
|
+
size="sm"
|
|
81
|
+
className="mt-2"
|
|
82
|
+
onClick={(e) => {
|
|
83
|
+
e.stopPropagation();
|
|
84
|
+
onManageClick();
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
88
87
|
Add Card
|
|
89
88
|
<ChevronRight className="h-4 w-4 ml-1" />
|
|
90
89
|
</Button>
|
|
@@ -98,18 +97,14 @@ export function PaymentMethodSummaryCard({
|
|
|
98
97
|
Expires {String(defaultMethod.card.expMonth).padStart(2, "0")}/{defaultMethod.card.expYear}
|
|
99
98
|
</p>
|
|
100
99
|
{paymentMethods.length > 1 && (
|
|
101
|
-
<p className="text-xs text-muted-foreground">
|
|
102
|
-
+{paymentMethods.length - 1} more card(s)
|
|
103
|
-
</p>
|
|
100
|
+
<p className="text-xs text-muted-foreground">+{paymentMethods.length - 1} more card(s)</p>
|
|
104
101
|
)}
|
|
105
102
|
</div>
|
|
106
103
|
) : (
|
|
107
104
|
<div className="space-y-2">
|
|
108
105
|
<p className="text-xl font-bold">{defaultMethod?.type || "Payment Method"}</p>
|
|
109
106
|
{paymentMethods.length > 1 && (
|
|
110
|
-
<p className="text-xs text-muted-foreground">
|
|
111
|
-
+{paymentMethods.length - 1} more method(s)
|
|
112
|
-
</p>
|
|
107
|
+
<p className="text-xs text-muted-foreground">+{paymentMethods.length - 1} more method(s)</p>
|
|
113
108
|
)}
|
|
114
109
|
</div>
|
|
115
110
|
)}
|
|
@@ -122,7 +122,13 @@ export function SubscriptionSummaryCard({
|
|
|
122
122
|
<div className="space-y-2">
|
|
123
123
|
<div className="flex items-center gap-2">
|
|
124
124
|
<p className="text-xl font-bold">{formatPlanName(primarySubscription)}</p>
|
|
125
|
-
<Badge
|
|
125
|
+
<Badge
|
|
126
|
+
variant={
|
|
127
|
+
primarySubscription.cancelAtPeriodEnd
|
|
128
|
+
? "secondary"
|
|
129
|
+
: getStatusBadgeVariant(primarySubscription.status)
|
|
130
|
+
}
|
|
131
|
+
>
|
|
126
132
|
{primarySubscription.cancelAtPeriodEnd ? "Canceling" : primarySubscription.status}
|
|
127
133
|
</Badge>
|
|
128
134
|
</div>
|