Skip to content

Commit 9985ac8

Browse files
author
FalkWolsky
committed
Rounding up Subscriptions
1 parent 4b8c585 commit 9985ac8

File tree

6 files changed

+68
-53
lines changed

6 files changed

+68
-53
lines changed

client/packages/lowcoder-cli/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
"vite-plugin-svgr": "^2.2.2"
3939
},
4040
"devDependencies": {
41-
"@types/axios": "^0.14.0",
4241
"typescript": "^4.8.4"
4342
},
4443
"peerDependencies": {

client/packages/lowcoder/src/api/subscriptionApi.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ const getAxiosInstance = (clientSecret?: string) => {
4343
};
4444

4545
class SubscriptionApi extends Api {
46-
static async secureRequest(body: any): Promise<any> {
46+
static async secureRequest(body: any, timeout: number = 6000): Promise<any> {
4747
let response;
4848
const axiosInstance = getAxiosInstance();
4949

5050
// Create a cancel token and set timeout for cancellation
5151
const source = axios.CancelToken.source();
5252
const timeoutId = setTimeout(() => {
5353
source.cancel("Request timed out.");
54-
}, 6000);
54+
}, timeout);
5555

5656
// Request configuration with cancel token
5757
const requestConfig: AxiosRequestConfig = {
@@ -174,7 +174,7 @@ export const createCustomer = async (subscriptionCustomer: LowcoderNewCustomer)
174174
headers: lcHeaders
175175
};
176176
try {
177-
const result = await SubscriptionApi.secureRequest(apiBody);
177+
const result = await SubscriptionApi.secureRequest(apiBody, 15000);
178178
return result?.data as StripeCustomer;
179179
} catch (error) {
180180
console.error("Error creating customer:", error);

client/packages/lowcoder/src/util/context/SimpleSubscriptionContext.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import { useSelector } from "react-redux";
88

99
export interface SubscriptionContextType {
1010
products: SubscriptionProduct[];
11+
productsLoaded: boolean;
1112
subscriptionProducts: any[],
1213
customer?: StripeCustomer;
1314
isCreatingCustomer: boolean;
15+
isCustomerInitializationComplete: boolean,
1416
customerDataError: boolean;
1517
subscriptionDataError?: string;
1618
checkoutLinkDataError: boolean;
@@ -23,9 +25,11 @@ export interface SubscriptionContextType {
2325

2426
const SimpleSubscriptionContext = createContext<SubscriptionContextType>({
2527
products: [],
28+
productsLoaded: false,
2629
subscriptionProducts: [],
2730
customer: undefined,
2831
isCreatingCustomer: false,
32+
isCustomerInitializationComplete: false, // Add this flag
2933
customerDataError: false,
3034
subscriptionDataError: undefined,
3135
checkoutLinkDataError: false,
@@ -84,17 +88,19 @@ export const SimpleSubscriptionContextProvider = (props: {
8488
const productData = await getProducts();
8589
setSubscriptionProducts(productData);
8690
} catch (err) {
87-
// setError("Failed to fetch product.");
88-
console.error("Failed to fetch product.", err);
91+
console.error("Failed to fetch products:", err);
8992
} finally {
93+
setProductsLoaded(true);
9094
setSubscriptionProductsLoading(false);
9195
}
9296
};
93-
94-
if (!Boolean(subscriptionProducts.length)) {
97+
98+
if (!productsLoaded && !subscriptionProductsLoading) {
99+
console.log("Outer context: Fetching products...");
100+
setSubscriptionProductsLoading(true);
95101
fetchProducts();
96102
}
97-
}, [subscriptionProducts]);
103+
}, [productsLoaded, subscriptionProductsLoading]);
98104

99105
useEffect(() => {
100106
const initializeCustomer = async () => {
@@ -119,13 +125,17 @@ export const SimpleSubscriptionContextProvider = (props: {
119125
}
120126
}, [deploymentId]);
121127

128+
const isCustomerInitializationComplete = !isCreatingCustomer && Boolean(customer);
129+
122130
return (
123131
<SimpleSubscriptionContext.Provider value={{
124132
admin,
125133
customer,
126134
products,
135+
productsLoaded,
127136
subscriptionProducts,
128137
isCreatingCustomer,
138+
isCustomerInitializationComplete,
129139
customerDataError,
130140
subscriptions,
131141
subscriptionDataLoaded,

client/packages/lowcoder/src/util/context/SubscriptionContext.tsx

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { getCurrentUser, getUser } from "@lowcoder-ee/redux/selectors/usersSelec
66
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
77
import { useSelector } from "react-redux";
88
import { useOrgUserCount } from "../hooks";
9+
import { useSimpleSubscriptionContext } from "./SimpleSubscriptionContext";
910

1011
export interface SubscriptionContextType {
1112
products: SubscriptionProduct[];
@@ -40,14 +41,21 @@ const SubscriptionContext = createContext<SubscriptionContextType>({
4041
export const SubscriptionContextProvider = (props: {
4142
children: ReactNode,
4243
}) => {
43-
const [customer, setCustomer] = useState<StripeCustomer>();
44-
const [isCreatingCustomer, setIsCreatingCustomer] = useState<boolean>(false); // Track customer creation
44+
45+
const {
46+
customer: existingCustomer,
47+
subscriptionProducts: existingProducts,
48+
productsLoaded,
49+
isCustomerInitializationComplete,
50+
} = useSimpleSubscriptionContext();
51+
52+
const [customer, setCustomer] = useState<StripeCustomer | undefined>(existingCustomer);
53+
const [isCreatingCustomer, setIsCreatingCustomer] = useState<boolean>(false);
4554
const [customerDataError, setCustomerDataError] = useState<boolean>(false);
4655
const [checkoutLinkDataLoaded, setCheckoutLinkDataLoaded] = useState<boolean>(false);
4756
const [checkoutLinkDataError, setCheckoutLinkDataError] = useState<boolean>(false);
4857
const [products, setProducts] = useState<SubscriptionProduct[]>(InitSubscriptionProducts);
49-
const [productsLoaded, setProductsLoaded] = useState<boolean>(false);
50-
const [subscriptionProducts, setSubscriptionProducts] = useState<any[]>([]);
58+
const [subscriptionProducts, setSubscriptionProducts] = useState<any[]>(existingProducts || []);
5159
const [subscriptionProductsLoading, setSubscriptionProductsLoading] = useState<boolean>(false);
5260

5361
const user = useSelector(getUser);
@@ -82,29 +90,32 @@ export const SubscriptionContextProvider = (props: {
8290
};
8391

8492
useEffect(() => {
85-
const fetchProducts = async () => {
86-
try {
87-
const productData = await getProducts();
88-
setSubscriptionProducts(productData);
89-
} catch (err) {
90-
// setError("Failed to fetch product.");
91-
console.error("Failed to fetch product.", err);
92-
} finally {
93-
setSubscriptionProductsLoading(false);
93+
// If products are already loaded in the outer context, reuse them
94+
if (productsLoaded) {
95+
if (!subscriptionProducts.length) {
96+
setSubscriptionProducts(existingProducts);
9497
}
95-
};
96-
97-
if (!Boolean(subscriptionProducts.length)) {
98-
fetchProducts();
98+
// Ensure no fetching happens in this case
99+
return;
99100
}
100-
}, [subscriptionProducts]);
101+
}, [productsLoaded, existingProducts, subscriptionProducts, subscriptionProductsLoading]);
101102

102103
useEffect(() => {
103104
const initializeCustomer = async () => {
104-
try {
105+
if (existingCustomer) {
106+
setCustomer(existingCustomer);
107+
return;
108+
}
109+
110+
/* try {
105111
setIsCreatingCustomer(true);
112+
const subscriptionSearchCustomer: LowcoderSearchCustomer = {
113+
hostId: deploymentId,
114+
orgId: orgID,
115+
userId: user.id,
116+
};
106117
const existingCustomer = await searchCustomer(subscriptionSearchCustomer);
107-
if (existingCustomer != null) {
118+
if (existingCustomer) {
108119
setCustomer(existingCustomer);
109120
} else {
110121
const newCustomer = await createCustomer(subscriptionNewCustomer);
@@ -114,19 +125,18 @@ export const SubscriptionContextProvider = (props: {
114125
setCustomerDataError(true);
115126
} finally {
116127
setIsCreatingCustomer(false);
117-
}
128+
} */
118129
};
119130

120-
if (Boolean(deploymentId) && !customer) {
131+
if (!customer && isCustomerInitializationComplete) {
121132
initializeCustomer();
122133
}
123-
}, [deploymentId]);
134+
}, [customer, existingCustomer, isCustomerInitializationComplete, deploymentId]);
124135

125136
useEffect(() => {
126137
const prepareCheckout = async () => {
127138
if (subscriptionDataLoaded && userCount > 0) { // Ensure user count is available
128139
try {
129-
console.log("Total Users in Organization:", userCount);
130140
const updatedProducts = await Promise.all(
131141
products.map(async (product) => {
132142
const matchingSubscription = subscriptions.find(
@@ -153,15 +163,14 @@ export const SubscriptionContextProvider = (props: {
153163
})
154164
);
155165
setProducts(updatedProducts);
156-
setProductsLoaded(true);
157166
setCheckoutLinkDataError(false);
158167
} catch (error) {
159168
setCheckoutLinkDataError(true);
160169
}
161170
}
162171
};
163172

164-
if (!productsLoaded && customer) {
173+
if (productsLoaded && customer) {
165174
prepareCheckout();
166175
}
167176
}, [subscriptionDataLoaded, customer, userCount]);

server/node-service/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"@google-cloud/bigquery": "^6.1.0",
4141
"@google-cloud/storage": "^6.10.1",
4242
"@supabase/supabase-js": "^2.26.0",
43-
"@types/axios": "^0.14.0",
4443
"@types/express": "^4.17.14",
4544
"@types/jsonpath": "^0.2.0",
4645
"@types/lodash": "^4.14.190",

server/node-service/yarn.lock

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,13 @@ __metadata:
23452345
languageName: node
23462346
linkType: hard
23472347

2348+
"@scarf/scarf@npm:=1.4.0":
2349+
version: 1.4.0
2350+
resolution: "@scarf/scarf@npm:1.4.0"
2351+
checksum: def62aa403f7e63165ccb219efd2c420fc0b7357b0ba43397f635e4aa813ace1cdf3855a93fc559b4619bcc0469ae4767b8cb72af30ea5c0522bf4a2ecb18198
2352+
languageName: node
2353+
linkType: hard
2354+
23482355
"@sinclair/typebox@npm:^0.27.8":
23492356
version: 0.27.8
23502357
resolution: "@sinclair/typebox@npm:0.27.8"
@@ -3587,15 +3594,6 @@ __metadata:
35873594
languageName: node
35883595
linkType: hard
35893596

3590-
"@types/axios@npm:^0.14.0":
3591-
version: 0.14.0
3592-
resolution: "@types/axios@npm:0.14.0"
3593-
dependencies:
3594-
axios: "*"
3595-
checksum: 12a230b9404055d81804cb57fe4739b2317111b28a39e2477b2513250e8b85725e6f6ce509fc2a9494a6da60facb8d80df875fcd747f62f6c3abebc7db60ae66
3596-
languageName: node
3597-
linkType: hard
3598-
35993597
"@types/babel__core@npm:^7.1.14":
36003598
version: 7.20.5
36013599
resolution: "@types/babel__core@npm:7.20.5"
@@ -4271,7 +4269,7 @@ __metadata:
42714269
languageName: node
42724270
linkType: hard
42734271

4274-
"axios@npm:*, axios@npm:^1.4.0, axios@npm:^1.7.7":
4272+
"axios@npm:^1.4.0, axios@npm:^1.7.7":
42754273
version: 1.7.7
42764274
resolution: "axios@npm:1.7.7"
42774275
dependencies:
@@ -7737,7 +7735,6 @@ __metadata:
77377735
"@google-cloud/storage": ^6.10.1
77387736
"@supabase/supabase-js": ^2.26.0
77397737
"@types/ali-oss": ^6.16.11
7740-
"@types/axios": ^0.14.0
77417738
"@types/express": ^4.17.14
77427739
"@types/jest": ^29.2.4
77437740
"@types/jsonpath": ^0.2.0
@@ -10047,10 +10044,11 @@ __metadata:
1004710044
linkType: hard
1004810045

1004910046
"swagger-client@npm:^3.29.3":
10050-
version: 3.29.4
10051-
resolution: "swagger-client@npm:3.29.4"
10047+
version: 3.31.0
10048+
resolution: "swagger-client@npm:3.31.0"
1005210049
dependencies:
1005310050
"@babel/runtime-corejs3": ^7.22.15
10051+
"@scarf/scarf": =1.4.0
1005410052
"@swagger-api/apidom-core": ">=1.0.0-alpha.9 <1.0.0-beta.0"
1005510053
"@swagger-api/apidom-error": ">=1.0.0-alpha.9 <1.0.0-beta.0"
1005610054
"@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.9 <1.0.0-beta.0"
@@ -10067,7 +10065,7 @@ __metadata:
1006710065
openapi-server-url-templating: ^1.0.0
1006810066
ramda: ^0.30.1
1006910067
ramda-adjunct: ^5.0.0
10070-
checksum: 62fba05a225901b01fa9ce767efa623a95d0bdb79753214f533476682644788e4629aa88d3e0cf4d86696fc6e14784095156a214ddfeeb82b940c2325a3c2a51
10068+
checksum: 86b414dda317d5e9ca6efac8c04355016106e9e637b9b0bfb7a27c43f4b14e18a18c93ac108798ecc0e00c1937036f79fe103b98f551ef1e24fd54e0c3b756b0
1007110069
languageName: node
1007210070
linkType: hard
1007310071

@@ -10901,11 +10899,11 @@ __metadata:
1090110899
linkType: hard
1090210900

1090310901
"yaml@npm:^2.2.2":
10904-
version: 2.5.1
10905-
resolution: "yaml@npm:2.5.1"
10902+
version: 2.6.0
10903+
resolution: "yaml@npm:2.6.0"
1090610904
bin:
1090710905
yaml: bin.mjs
10908-
checksum: 31275223863fbd0b47ba9d2b248fbdf085db8d899e4ca43fff8a3a009497c5741084da6871d11f40e555d61360951c4c910b98216c1325d2c94753c0036d8172
10906+
checksum: e5e74fd75e01bde2c09333d529af9fbb5928c5f7f01bfdefdcb2bf753d4ef489a45cab4deac01c9448f55ca27e691612b81fe3c3a59bb8cb5b0069da0f92cf0b
1090910907
languageName: node
1091010908
linkType: hard
1091110909

0 commit comments

Comments
 (0)