@carlonicora/nextjs-jsonapi 1.28.0 → 1.29.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-CAUNVZUF.js → BlockNoteEditor-YBVEOPV4.js} +13 -13
- package/dist/{BlockNoteEditor-CAUNVZUF.js.map → BlockNoteEditor-YBVEOPV4.js.map} +1 -1
- package/dist/{BlockNoteEditor-EOA4OEVX.mjs → BlockNoteEditor-ZM4YPXHO.mjs} +3 -3
- package/dist/billing/index.d.mts +47 -17
- package/dist/billing/index.d.ts +47 -17
- package/dist/billing/index.js +1241 -1073
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +1375 -1207
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-IXI4GAKB.js → chunk-3X7EEFMN.js} +488 -431
- package/dist/chunk-3X7EEFMN.js.map +1 -0
- package/dist/{chunk-ORFXBO7F.mjs → chunk-DU64WMZD.mjs} +6 -3
- package/dist/chunk-DU64WMZD.mjs.map +1 -0
- package/dist/{chunk-TSEU4KZ2.js → chunk-J22NEVSK.js} +21 -18
- package/dist/chunk-J22NEVSK.js.map +1 -0
- package/dist/{chunk-PYASRX75.mjs → chunk-UCD5CUE4.mjs} +81 -24
- package/dist/chunk-UCD5CUE4.mjs.map +1 -0
- package/dist/client/index.d.mts +14 -5
- package/dist/client/index.d.ts +14 -5
- package/dist/client/index.js +5 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -2
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.mjs +2 -2
- package/dist/{config-B4pZpLT9.d.ts → config-CHwoRDOp.d.ts} +1 -1
- package/dist/{config-DT1K-t6I.d.mts → config-DiWyJzk9.d.mts} +1 -1
- package/dist/{content.interface-B2Ldg0vg.d.mts → content.interface-BSpowEiW.d.mts} +1 -1
- package/dist/{content.interface-D8NHv3DX.d.ts → content.interface-DFQ7mkpL.d.ts} +1 -1
- package/dist/contexts/index.d.mts +2 -2
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +39 -37
- package/dist/core/index.d.ts +39 -37
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notification.interface-H0L9WBge.d.ts → notification.interface-CmKmObIU.d.ts} +1 -0
- package/dist/{notification.interface-DEn-Yp_b.d.mts → notification.interface-D5MbtfZK.d.mts} +1 -0
- package/dist/{s3.service-BNytYanU.d.mts → s3.service-BMT7W6KS.d.mts} +19 -19
- package/dist/{s3.service-C7f_Ygz5.d.ts → s3.service-DsXo9nop.d.ts} +19 -19
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/{useSocket-BcnThTD0.d.mts → useSocket-DUqGoPya.d.mts} +1 -1
- package/dist/{useSocket-QZTOCzRF.d.ts → useSocket-QuHa0ZmO.d.ts} +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +1 -0
- package/src/components/forms/FormSelect.tsx +2 -1
- package/src/features/auth/data/auth.ts +0 -2
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +60 -3
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +12 -152
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +168 -0
- package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +19 -1
- package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -235
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +7 -18
- package/src/features/billing/stripe-subscription/components/forms/index.ts +0 -1
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +10 -1
- package/src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx +28 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx +128 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +54 -0
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +68 -0
- package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -1
- package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +114 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +66 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +32 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx +103 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +133 -0
- package/src/features/billing/stripe-subscription/components/wizards/index.ts +6 -0
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +217 -0
- package/src/features/billing/stripe-subscription/index.ts +3 -2
- package/src/features/company/components/details/TokenStatusIndicator.tsx +19 -9
- package/src/features/company/data/company.interface.ts +2 -0
- package/src/features/company/data/company.ts +7 -0
- package/src/features/company/hooks/index.ts +1 -0
- package/src/features/company/hooks/useSubscriptionStatus.ts +71 -0
- package/src/features/user/components/forms/UserEditor.tsx +1 -1
- package/src/features/user/components/lists/AdminUsersList.tsx +1 -1
- package/src/features/user/contexts/CurrentUserContext.tsx +1 -1
- package/src/features/user/data/user.ts +1 -1
- package/dist/chunk-IXI4GAKB.js.map +0 -1
- package/dist/chunk-ORFXBO7F.mjs.map +0 -1
- package/dist/chunk-PYASRX75.mjs.map +0 -1
- package/dist/chunk-TSEU4KZ2.js.map +0 -1
- package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +0 -331
- package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +0 -110
- /package/dist/{BlockNoteEditor-EOA4OEVX.mjs.map → BlockNoteEditor-ZM4YPXHO.mjs.map} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Battery, BatteryFull, BatteryLow, BatteryMedium, PlusCircle } from "lucide-react";
|
|
4
|
+
import Link from "next/link";
|
|
4
5
|
|
|
5
6
|
import { cn } from "@/lib/utils";
|
|
6
7
|
import { useTranslations } from "next-intl";
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from "../../../../shadcnui";
|
|
8
|
+
import { Button, Separator, Tooltip, TooltipContent, TooltipTrigger } from "../../../../shadcnui";
|
|
8
9
|
import { useCurrentUserContext } from "../../../user/contexts";
|
|
9
10
|
|
|
10
11
|
interface TokenStatusIndicatorProps {
|
|
@@ -99,14 +100,23 @@ export function TokenStatusIndicator({ className, size = "md", showExtraPages =
|
|
|
99
100
|
<span className="text-muted-foreground">{t("generic.tokens.available", { defaultValue: "Available" })}:</span>
|
|
100
101
|
<span className={cn("font-medium", getStatusColor())}>{percentage.toFixed(0)}%</span>
|
|
101
102
|
</div>
|
|
102
|
-
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
<Link href="/settings/billing?action=subscribe" className="w-full flex justify-end my-4">
|
|
104
|
+
<Button variant="outline" size="sm">
|
|
105
|
+
{t("generic.tokens.upgrade_plan", { defaultValue: "Upgrade plan" })}
|
|
106
|
+
</Button>
|
|
107
|
+
</Link>
|
|
108
|
+
<Separator />
|
|
109
|
+
<div className="flex items-center justify-between gap-4 pt-1 mt-1">
|
|
110
|
+
<span className="text-muted-foreground">
|
|
111
|
+
{t("generic.tokens.available_extra", { defaultValue: "Extra Pages" })}:
|
|
112
|
+
</span>
|
|
113
|
+
<span className="font-medium text-blue-500">{availableExtraTokens}</span>
|
|
114
|
+
</div>
|
|
115
|
+
<Link href="/settings/billing?action=subscribe" className="w-full flex justify-end my-4">
|
|
116
|
+
<Button variant="outline" size="sm">
|
|
117
|
+
{t("generic.tokens.purchase_extra", { defaultValue: "Purchase additional analysis" })}
|
|
118
|
+
</Button>
|
|
119
|
+
</Link>
|
|
110
120
|
</div>
|
|
111
121
|
</div>
|
|
112
122
|
);
|
|
@@ -22,6 +22,8 @@ export interface CompanyInterface extends ApiDataInterface {
|
|
|
22
22
|
get logo(): string | undefined;
|
|
23
23
|
get logoUrl(): string | undefined;
|
|
24
24
|
|
|
25
|
+
get isActiveSubscription(): boolean;
|
|
26
|
+
|
|
25
27
|
get monthlyTokens(): number;
|
|
26
28
|
get availableMonthlyTokens(): number;
|
|
27
29
|
get availableExtraTokens(): number;
|
|
@@ -9,6 +9,8 @@ export class Company extends AbstractApiData implements CompanyInterface {
|
|
|
9
9
|
private _logoUrl?: string;
|
|
10
10
|
private _configurations?: any;
|
|
11
11
|
|
|
12
|
+
private _isActiveSubscription: boolean = false;
|
|
13
|
+
|
|
12
14
|
private _monthlyTokens: number = 0;
|
|
13
15
|
private _availableMonthlyTokens: number = 0;
|
|
14
16
|
private _availableExtraTokens: number = 0;
|
|
@@ -29,6 +31,10 @@ export class Company extends AbstractApiData implements CompanyInterface {
|
|
|
29
31
|
return this._logoUrl;
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
get isActiveSubscription(): boolean {
|
|
35
|
+
return this._isActiveSubscription ?? false;
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
get monthlyTokens(): number {
|
|
33
39
|
return this._monthlyTokens ?? 0;
|
|
34
40
|
}
|
|
@@ -62,6 +68,7 @@ export class Company extends AbstractApiData implements CompanyInterface {
|
|
|
62
68
|
: undefined;
|
|
63
69
|
this._logo = data.jsonApi.attributes.logo;
|
|
64
70
|
this._logoUrl = data.jsonApi.attributes.logoUrl;
|
|
71
|
+
this._isActiveSubscription = data.jsonApi.attributes.isActiveSubscription ?? false;
|
|
65
72
|
this._monthlyTokens = data.jsonApi.attributes.monthlyTokens ?? 0;
|
|
66
73
|
this._availableMonthlyTokens = data.jsonApi.attributes.availableMonthlyTokens ?? 0;
|
|
67
74
|
this._availableExtraTokens = data.jsonApi.attributes.availableExtraTokens ?? 0;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { useCurrentUserContext } from "../../user/contexts/CurrentUserContext";
|
|
5
|
+
|
|
6
|
+
export interface TrialSubscriptionStatus {
|
|
7
|
+
status: "loading" | "trial" | "active" | "expired";
|
|
8
|
+
trialEndsAt: Date | null;
|
|
9
|
+
daysRemaining: number;
|
|
10
|
+
isGracePeriod: boolean; // Last 3 days
|
|
11
|
+
isBlocked: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const TRIAL_DAYS = 14;
|
|
15
|
+
const GRACE_DAYS = 3;
|
|
16
|
+
|
|
17
|
+
export function useSubscriptionStatus(): TrialSubscriptionStatus {
|
|
18
|
+
const { company, currentUser } = useCurrentUserContext();
|
|
19
|
+
|
|
20
|
+
return useMemo(() => {
|
|
21
|
+
// Still loading user data - don't block yet
|
|
22
|
+
if (currentUser === null) {
|
|
23
|
+
return {
|
|
24
|
+
status: "loading",
|
|
25
|
+
trialEndsAt: null,
|
|
26
|
+
daysRemaining: 0,
|
|
27
|
+
isGracePeriod: false,
|
|
28
|
+
isBlocked: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// No company after loading = blocked
|
|
33
|
+
if (!company) {
|
|
34
|
+
return {
|
|
35
|
+
status: "expired",
|
|
36
|
+
trialEndsAt: null,
|
|
37
|
+
daysRemaining: 0,
|
|
38
|
+
isGracePeriod: false,
|
|
39
|
+
isBlocked: true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Has active subscription = never blocked
|
|
44
|
+
if (company.isActiveSubscription) {
|
|
45
|
+
return {
|
|
46
|
+
status: "active",
|
|
47
|
+
trialEndsAt: null,
|
|
48
|
+
daysRemaining: 0,
|
|
49
|
+
isGracePeriod: false,
|
|
50
|
+
isBlocked: false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Calculate trial status from createdAt
|
|
55
|
+
const createdAt = new Date(company.createdAt);
|
|
56
|
+
const trialEndsAt = new Date(createdAt);
|
|
57
|
+
trialEndsAt.setDate(trialEndsAt.getDate() + TRIAL_DAYS);
|
|
58
|
+
|
|
59
|
+
const now = new Date();
|
|
60
|
+
const msRemaining = trialEndsAt.getTime() - now.getTime();
|
|
61
|
+
const daysRemaining = Math.ceil(msRemaining / (1000 * 60 * 60 * 24));
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
status: daysRemaining > 0 ? "trial" : "expired",
|
|
65
|
+
trialEndsAt,
|
|
66
|
+
daysRemaining: Math.max(0, daysRemaining),
|
|
67
|
+
isGracePeriod: daysRemaining > 0 && daysRemaining <= GRACE_DAYS,
|
|
68
|
+
isBlocked: daysRemaining <= 0,
|
|
69
|
+
};
|
|
70
|
+
}, [company, currentUser]);
|
|
71
|
+
}
|
|
@@ -23,7 +23,7 @@ import { useI18nRouter, usePageUrlGenerator } from "../../../../hooks";
|
|
|
23
23
|
import { Action } from "../../../../permissions";
|
|
24
24
|
import { getRoleId } from "../../../../roles";
|
|
25
25
|
import { Dialog, DialogContent, DialogTrigger, Form } from "../../../../shadcnui";
|
|
26
|
-
import { CompanyInterface } from "../../../company";
|
|
26
|
+
import { CompanyInterface } from "../../../company/data/company.interface";
|
|
27
27
|
import { RoleInterface } from "../../../role";
|
|
28
28
|
import { RoleService } from "../../../role/data/role.service";
|
|
29
29
|
import { S3Interface } from "../../../s3";
|
|
@@ -5,7 +5,7 @@ import { ContentListTable } from "../../../../components";
|
|
|
5
5
|
import { useCompanyContext } from "../../../../contexts";
|
|
6
6
|
import { Modules } from "../../../../core";
|
|
7
7
|
import { DataListRetriever, useDataListRetriever } from "../../../../hooks";
|
|
8
|
-
import { CompanyInterface } from "../../../company";
|
|
8
|
+
import { CompanyInterface } from "../../../company/data/company.interface";
|
|
9
9
|
import { UserFields, UserInterface } from "../../data";
|
|
10
10
|
import { UserService } from "../../data/user.service";
|
|
11
11
|
import { UserEditor } from "../forms";
|
|
@@ -8,7 +8,7 @@ import React, { createContext, useCallback, useContext, useEffect, useRef, useSt
|
|
|
8
8
|
import { Modules, rehydrate } from "../../../core";
|
|
9
9
|
import { Action, checkPermissions, ModuleWithPermissions } from "../../../permissions";
|
|
10
10
|
import { getRoleId } from "../../../roles";
|
|
11
|
-
import { CompanyInterface } from "../../company";
|
|
11
|
+
import { CompanyInterface } from "../../company/data/company.interface";
|
|
12
12
|
import { FeatureInterface } from "../../feature";
|
|
13
13
|
import { RoleInterface } from "../../role";
|
|
14
14
|
import { UserInterface, UserService } from "../data";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from "../../../core";
|
|
2
|
-
import { CompanyInterface } from "../../company";
|
|
2
|
+
import { CompanyInterface } from "../../company/data/company.interface";
|
|
3
3
|
import { ModuleInterface } from "../../module";
|
|
4
4
|
import { RoleInterface } from "../../role";
|
|
5
5
|
import { SearchResultInterface } from "../../search";
|