Finish removing Stripe from codebase

This commit is contained in:
Tuan Dang
2023-06-22 16:38:02 +07:00
parent f3e84dc6eb
commit 28943f3b6f
25 changed files with 52 additions and 290 deletions
-7
View File
@@ -61,13 +61,6 @@ SENTRY_DSN=
# Ignore - Not applicable for self-hosted version # Ignore - Not applicable for self-hosted version
POSTHOG_HOST= POSTHOG_HOST=
POSTHOG_PROJECT_API_KEY= POSTHOG_PROJECT_API_KEY=
STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRODUCT_STARTER=
STRIPE_PRODUCT_TEAM=
STRIPE_PRODUCT_PRO=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
CLIENT_ID_GOOGLE= CLIENT_ID_GOOGLE=
CLIENT_SECRET_GOOGLE= CLIENT_SECRET_GOOGLE=
+1
View File
@@ -2,6 +2,7 @@
node_modules node_modules
.env .env
.env.dev .env.dev
.env.gamma
.env.prod .env.prod
.env.infisical .env.infisical
-6
View File
@@ -39,12 +39,6 @@ declare global {
SMTP_PASSWORD: string; SMTP_PASSWORD: string;
SMTP_FROM_ADDRESS: string; SMTP_FROM_ADDRESS: string;
SMTP_FROM_NAME: string; SMTP_FROM_NAME: string;
STRIPE_PRODUCT_STARTER: string;
STRIPE_PRODUCT_TEAM: string;
STRIPE_PRODUCT_PRO: string;
STRIPE_PUBLISHABLE_KEY: string;
STRIPE_SECRET_KEY: string;
STRIPE_WEBHOOK_SECRET: string;
TELEMETRY_ENABLED: string; TELEMETRY_ENABLED: string;
LICENSE_KEY: string; LICENSE_KEY: string;
} }
-22
View File
@@ -50,7 +50,6 @@
"query-string": "^7.1.3", "query-string": "^7.1.3",
"rate-limit-mongo": "^2.3.2", "rate-limit-mongo": "^2.3.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"stripe": "^10.7.0",
"swagger-autogen": "^2.22.0", "swagger-autogen": "^2.22.0",
"swagger-ui-express": "^4.6.2", "swagger-ui-express": "^4.6.2",
"tweetnacl": "^1.0.3", "tweetnacl": "^1.0.3",
@@ -11588,18 +11587,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/stripe": {
"version": "10.17.0",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-10.17.0.tgz",
"integrity": "sha512-JHV2KoL+nMQRXu3m9ervCZZvi4DDCJfzHUE6CmtJxR9TmizyYfrVuhGvnsZLLnheby9Qrnf4Hq6iOEcejGwnGQ==",
"dependencies": {
"@types/node": ">=8.1.0",
"qs": "^6.11.0"
},
"engines": {
"node": "^8.1 || >=10.*"
}
},
"node_modules/strnum": { "node_modules/strnum": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
@@ -21096,15 +21083,6 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true "dev": true
}, },
"stripe": {
"version": "10.17.0",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-10.17.0.tgz",
"integrity": "sha512-JHV2KoL+nMQRXu3m9ervCZZvi4DDCJfzHUE6CmtJxR9TmizyYfrVuhGvnsZLLnheby9Qrnf4Hq6iOEcejGwnGQ==",
"requires": {
"@types/node": ">=8.1.0",
"qs": "^6.11.0"
}
},
"strnum": { "strnum": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
-1
View File
@@ -41,7 +41,6 @@
"query-string": "^7.1.3", "query-string": "^7.1.3",
"rate-limit-mongo": "^2.3.2", "rate-limit-mongo": "^2.3.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"stripe": "^10.7.0",
"swagger-autogen": "^2.22.0", "swagger-autogen": "^2.22.0",
"swagger-ui-express": "^4.6.2", "swagger-ui-express": "^4.6.2",
"tweetnacl": "^1.0.3", "tweetnacl": "^1.0.3",
-8
View File
@@ -67,14 +67,6 @@ export const getLicenseServerKey = async () => {
} }
export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com"; export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com";
// TODO: deprecate from here
export const getStripeProductStarter = async () => (await client.getSecret("STRIPE_PRODUCT_STARTER")).secretValue;
export const getStripeProductPro = async () => (await client.getSecret("STRIPE_PRODUCT_PRO")).secretValue;
export const getStripeProductTeam = async () => (await client.getSecret("STRIPE_PRODUCT_TEAM")).secretValue;
export const getStripePublishableKey = async () => (await client.getSecret("STRIPE_PUBLISHABLE_KEY")).secretValue;
export const getStripeSecretKey = async () => (await client.getSecret("STRIPE_SECRET_KEY")).secretValue;
export const getStripeWebhookSecret = async () => (await client.getSecret("STRIPE_WEBHOOK_SECRET")).secretValue;
export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true; export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true;
export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue; export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue;
export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true
-2
View File
@@ -10,7 +10,6 @@ import * as passwordController from "./passwordController";
import * as secretController from "./secretController"; import * as secretController from "./secretController";
import * as serviceTokenController from "./serviceTokenController"; import * as serviceTokenController from "./serviceTokenController";
import * as signupController from "./signupController"; import * as signupController from "./signupController";
import * as stripeController from "./stripeController";
import * as userActionController from "./userActionController"; import * as userActionController from "./userActionController";
import * as userController from "./userController"; import * as userController from "./userController";
import * as workspaceController from "./workspaceController"; import * as workspaceController from "./workspaceController";
@@ -28,7 +27,6 @@ export {
secretController, secretController,
serviceTokenController, serviceTokenController,
signupController, signupController,
stripeController,
userActionController, userActionController,
userController, userController,
workspaceController, workspaceController,
@@ -1,5 +1,4 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import Stripe from "stripe";
import { import {
IncidentContactOrg, IncidentContactOrg,
Membership, Membership,
@@ -10,7 +9,8 @@ import {
import { createOrganization as create } from "../../helpers/organization"; import { createOrganization as create } from "../../helpers/organization";
import { addMembershipsOrg } from "../../helpers/membershipOrg"; import { addMembershipsOrg } from "../../helpers/membershipOrg";
import { ACCEPTED, OWNER } from "../../variables"; import { ACCEPTED, OWNER } from "../../variables";
import { getSiteURL, getStripeSecretKey } from "../../config"; import { getSiteURL, getLicenseServerUrl } from "../../config";
import { licenseServerKeyRequest } from "../../config/request";
export const getOrganizations = async (req: Request, res: Response) => { export const getOrganizations = async (req: Request, res: Response) => {
const organizations = ( const organizations = (
@@ -222,7 +222,7 @@ export const deleteOrganizationIncidentContact = async (
}; };
/** /**
* Redirect user to (stripe) billing portal or add card page depending on * Redirect user to billing portal or add card page depending on
* if there is a card on file * if there is a card on file
* @param req * @param req
* @param res * @param res
@@ -232,34 +232,32 @@ export const createOrganizationPortalSession = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
let session; const { data: { pmtMethods } } = await licenseServerKeyRequest.get(
const stripe = new Stripe(await getStripeSecretKey(), { `${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/payment-methods`,
apiVersion: "2022-08-01", );
});
// check if there is a payment method on file if (pmtMethods.length < 1) {
const paymentMethods = await stripe.paymentMethods.list({ // case: organization has no payment method on file
customer: req.organization.customerId, // -> redirect to add payment method portal
type: "card", const { data: { url } } = await licenseServerKeyRequest.post(
}); `${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/payment-methods`,
{
if (paymentMethods.data.length < 1) { success_url: (await getSiteURL()) + "/dashboard",
// case: no payment method on file cancel_url: (await getSiteURL()) + "/dashboard"
session = await stripe.checkout.sessions.create({ }
customer: req.organization.customerId, );
mode: "setup", return res.status(200).send({ url });
payment_method_types: ["card"],
success_url: (await getSiteURL()) + "/dashboard",
cancel_url: (await getSiteURL()) + "/dashboard",
});
} else { } else {
session = await stripe.billingPortal.sessions.create({ // case: organization has payment method on file
customer: req.organization.customerId, // -> redirect to billing portal
return_url: (await getSiteURL()) + "/dashboard", const { data: { url } } = await licenseServerKeyRequest.post(
}); `${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/billing-portal`,
{
return_url: (await getSiteURL()) + "/dashboard"
}
);
return res.status(200).send({ url });
} }
return res.status(200).send({ url: session.url });
}; };
/** /**
@@ -272,16 +270,8 @@ export const getOrganizationSubscriptions = async (
req: Request, req: Request,
res: Response res: Response
) => { ) => {
const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: "2022-08-01",
});
const subscriptions = await stripe.subscriptions.list({
customer: req.organization.customerId,
});
return res.status(200).send({ return res.status(200).send({
subscriptions, subscriptions: []
}); });
}; };
@@ -1,31 +0,0 @@
import { Request, Response } from "express";
import Stripe from "stripe";
import { getStripeSecretKey, getStripeWebhookSecret } from "../../config";
/**
* Handle service provisioning/un-provisioning via Stripe
* @param req
* @param res
* @returns
*/
export const handleWebhook = async (req: Request, res: Response) => {
// check request for valid stripe signature
const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: "2022-08-01",
});
const sig = req.headers["stripe-signature"] as string;
const event = stripe.webhooks.constructEvent(
req.body,
sig,
await getStripeWebhookSecret()
);
switch (event.type) {
case "":
break;
default:
}
return res.json({ received: true });
};
-2
View File
@@ -1,4 +1,3 @@
import * as stripeController from "./stripeController";
import * as secretController from "./secretController"; import * as secretController from "./secretController";
import * as secretSnapshotController from "./secretSnapshotController"; import * as secretSnapshotController from "./secretSnapshotController";
import * as organizationsController from "./organizationsController"; import * as organizationsController from "./organizationsController";
@@ -8,7 +7,6 @@ import * as membershipController from "./membershipController";
import * as cloudProductsController from "./cloudProductsController"; import * as cloudProductsController from "./cloudProductsController";
export { export {
stripeController,
secretController, secretController,
secretSnapshotController, secretSnapshotController,
organizationsController, organizationsController,
@@ -52,7 +52,7 @@ export const getOrganizationPmtMethods = async (req: Request, res: Response) =>
} }
/** /**
* Return a Stripe session URL to add payment method for organization * Return URL to add payment method for organization
*/ */
export const addOrganizationPmtMethod = async (req: Request, res: Response) => { export const addOrganizationPmtMethod = async (req: Request, res: Response) => {
const { const {
@@ -1,31 +0,0 @@
import { Request, Response } from "express";
import Stripe from "stripe";
import { getStripeSecretKey, getStripeWebhookSecret } from "../../../config";
/**
* Handle service provisioning/un-provisioning via Stripe
* @param req
* @param res
* @returns
*/
export const handleWebhook = async (req: Request, res: Response) => {
const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: "2022-08-01",
});
// check request for valid stripe signature
const sig = req.headers["stripe-signature"] as string;
const event = stripe.webhooks.constructEvent(
req.body,
sig,
await getStripeWebhookSecret()
);
switch (event.type) {
case "":
break;
default:
}
return res.json({ received: true });
};
-7
View File
@@ -1,7 +0,0 @@
import express from "express";
const router = express.Router();
import { stripeController } from "../../controllers/v1";
router.post("/webhook", stripeController.handleWebhook);
export default router;
+11 -79
View File
@@ -1,19 +1,13 @@
import Stripe from "stripe";
import { Types } from "mongoose"; import { Types } from "mongoose";
import { MembershipOrg, Organization } from "../models"; import { MembershipOrg, Organization } from "../models";
import { import {
ACCEPTED, ACCEPTED,
} from "../variables"; } from "../variables";
import {
getStripeProductPro,
getStripeProductStarter,
getStripeProductTeam,
getStripeSecretKey,
} from "../config";
import { import {
EELicenseService, EELicenseService,
} from "../ee/services"; } from "../ee/services";
import { import {
getLicenseServerKey,
getLicenseServerUrl, getLicenseServerUrl,
} from "../config"; } from "../config";
import { import {
@@ -35,21 +29,21 @@ export const createOrganization = async ({
name: string; name: string;
email: string; email: string;
}) => { }) => {
const licenseServerKey = await getLicenseServerKey();
let organization; let organization;
// register stripe account
const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: "2022-08-01",
});
if (await getStripeSecretKey()) { if (licenseServerKey) {
const customer = await stripe.customers.create({ const { data: { customerId } } = await licenseServerKeyRequest.post(
email, `${await getLicenseServerUrl()}/api/license-server/v1/customers`,
description: name, {
}); email,
name
}
);
organization = await new Organization({ organization = await new Organization({
name, name,
customerId: customer.id, customerId
}).save(); }).save();
} else { } else {
organization = await new Organization({ organization = await new Organization({
@@ -57,68 +51,9 @@ export const createOrganization = async ({
}).save(); }).save();
} }
await initSubscriptionOrg({ organizationId: organization._id });
return organization; return organization;
}; };
/**
* Initialize free-tier subscription for new organization
* @param {Object} obj
* @param {String} obj.organizationId - id of associated organization for subscription
* @return {Object} obj
* @return {Object} obj.stripeSubscription - new stripe subscription
* @return {Subscription} obj.subscription - new subscription
*/
export const initSubscriptionOrg = async ({
organizationId,
}: {
organizationId: Types.ObjectId;
}) => {
let stripeSubscription;
let subscription;
// find organization
const organization = await Organization.findOne({
_id: organizationId,
});
if (organization) {
if (organization.customerId) {
// initialize starter subscription with quantity of 0
const stripe = new Stripe(await getStripeSecretKey(), {
apiVersion: "2022-08-01",
});
const productToPriceMap = {
starter: await getStripeProductStarter(),
team: await getStripeProductTeam(),
pro: await getStripeProductPro(),
};
stripeSubscription = await stripe.subscriptions.create({
customer: organization.customerId,
items: [
{
price: productToPriceMap["starter"],
quantity: 1,
},
],
payment_behavior: "default_incomplete",
proration_behavior: "none",
expand: ["latest_invoice.payment_intent"],
});
}
} else {
throw new Error("Failed to initialize free organization subscription");
}
return {
stripeSubscription,
subscription,
};
};
/** /**
* Update organization subscription quantity to reflect number of members in * Update organization subscription quantity to reflect number of members in
* the organization. * the organization.
@@ -130,7 +65,6 @@ export const updateSubscriptionOrgQuantity = async ({
}: { }: {
organizationId: string; organizationId: string;
}) => { }) => {
let stripeSubscription;
// find organization // find organization
const organization = await Organization.findOne({ const organization = await Organization.findOne({
_id: organizationId, _id: organizationId,
@@ -171,6 +105,4 @@ export const updateSubscriptionOrgQuantity = async ({
} }
await EELicenseService.refreshPlan(organizationId); await EELicenseService.refreshPlan(organizationId);
return stripeSubscription;
}; };
-2
View File
@@ -37,7 +37,6 @@ import {
secretsFolder as v1SecretsFolder, secretsFolder as v1SecretsFolder,
serviceToken as v1ServiceTokenRouter, serviceToken as v1ServiceTokenRouter,
signup as v1SignupRouter, signup as v1SignupRouter,
stripe as v1StripeRouter,
userAction as v1UserActionRouter, userAction as v1UserActionRouter,
user as v1UserRouter, user as v1UserRouter,
workspace as v1WorkspaceRouter, workspace as v1WorkspaceRouter,
@@ -123,7 +122,6 @@ const main = async () => {
app.use("/api/v1/secret", v1SecretRouter); // deprecate app.use("/api/v1/secret", v1SecretRouter); // deprecate
app.use("/api/v1/service-token", v1ServiceTokenRouter); // deprecate app.use("/api/v1/service-token", v1ServiceTokenRouter); // deprecate
app.use("/api/v1/password", v1PasswordRouter); app.use("/api/v1/password", v1PasswordRouter);
app.use("/api/v1/stripe", v1StripeRouter);
app.use("/api/v1/integration", v1IntegrationRouter); app.use("/api/v1/integration", v1IntegrationRouter);
app.use("/api/v1/integration-auth", v1IntegrationAuthRouter); app.use("/api/v1/integration-auth", v1IntegrationAuthRouter);
app.use("/api/v1/folders", v1SecretsFolder); app.use("/api/v1/folders", v1SecretsFolder);
-2
View File
@@ -12,7 +12,6 @@ import inviteOrg from "./inviteOrg";
import secret from "./secret"; import secret from "./secret";
import serviceToken from "./serviceToken"; import serviceToken from "./serviceToken";
import password from "./password"; import password from "./password";
import stripe from "./stripe";
import integration from "./integration"; import integration from "./integration";
import integrationAuth from "./integrationAuth"; import integrationAuth from "./integrationAuth";
import secretsFolder from "./secretsFolder"; import secretsFolder from "./secretsFolder";
@@ -32,7 +31,6 @@ export {
secret, secret,
serviceToken, serviceToken,
password, password,
stripe,
integration, integration,
integrationAuth, integrationAuth,
secretsFolder, secretsFolder,
-7
View File
@@ -1,7 +0,0 @@
import express from "express";
const router = express.Router();
import { stripeController } from "../../controllers/v1";
router.post("/webhook", stripeController.handleWebhook);
export default router;
-1
View File
@@ -8,6 +8,5 @@ export * from "./organization";
export * from "./permission"; export * from "./permission";
export * from "./secret"; export * from "./secret";
export * from "./smtp"; export * from "./smtp";
export * from "./stripe";
export * from "./token"; export * from "./token";
export * from "./user"; export * from "./user";
-2
View File
@@ -1,2 +0,0 @@
export const PLAN_STARTER = "starter";
export const PLAN_PRO = "pro";
-3
View File
@@ -55,9 +55,6 @@ services:
environment: environment:
- NEXT_PUBLIC_ENV=development - NEXT_PUBLIC_ENV=development
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED} - INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
- NEXT_PUBLIC_STRIPE_PRODUCT_TEAM=${STRIPE_PRODUCT_TEAM}
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
networks: networks:
- infisical-dev - infisical-dev
-3
View File
@@ -38,9 +38,6 @@ services:
environment: environment:
# - NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY} # - NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY}
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED} - INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
- NEXT_PUBLIC_STRIPE_PRODUCT_TEAM=${STRIPE_PRODUCT_TEAM}
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
networks: networks:
- infisical - infisical
@@ -2,14 +2,11 @@ const ENV = process.env.NEXT_PUBLIC_ENV! || "development"; // investigate
const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!; const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!;
const POSTHOG_HOST = const POSTHOG_HOST =
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com"; process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
const INTERCOM_ID = process.env.NEXT_PUBLIC_INTERCOM_ID!; const INTERCOM_ID = process.env.NEXT_PUBLIC_INTERCOM_ID!;
export { export {
ENV, ENV,
INTERCOM_ID, INTERCOM_ID,
POSTHOG_API_KEY, POSTHOG_API_KEY,
POSTHOG_HOST, POSTHOG_HOST
STRIPE_PRODUCT_PRO, };
STRIPE_PRODUCT_STARTER};
+7 -27
View File
@@ -1,16 +1,12 @@
import { useEffect, useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import Head from "next/head"; import Head from "next/head";
import Plan from "@app/components/billing/Plan"; import Plan from "@app/components/billing/Plan";
import NavHeader from "@app/components/navigation/NavHeader"; import NavHeader from "@app/components/navigation/NavHeader";
import { plans as plansConstant } from "@app/const"; import { useSubscription } from "@app/context";
import getOrganizationSubscriptions from "../../api/organization/GetOrgSubscription";
import getOrganizationUsers from "../../api/organization/GetOrgUsers";
export default function SettingsBilling() { export default function SettingsBilling() {
const [currentPlan, setCurrentPlan] = useState(""); const { subscription } = useSubscription();
const [numUsers, setNumUsers] = useState(0); const [numUsers, setNumUsers] = useState(0);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -25,7 +21,7 @@ export default function SettingsBilling() {
subtext: t("billing.starter.subtext")!, subtext: t("billing.starter.subtext")!,
buttonTextMain: t("billing.downgrade")!, buttonTextMain: t("billing.downgrade")!,
buttonTextSecondary: t("billing.learn-more")!, buttonTextSecondary: t("billing.learn-more")!,
current: currentPlan === plansConstant.starter current: subscription?.slug === "starter" // subscription.slug?
}, },
{ {
key: 2, key: 2,
@@ -35,7 +31,7 @@ export default function SettingsBilling() {
text: "Unlimited members, up to 10 projects. Additional developer experience features.", text: "Unlimited members, up to 10 projects. Additional developer experience features.",
buttonTextMain: t("billing.upgrade")!, buttonTextMain: t("billing.upgrade")!,
buttonTextSecondary: t("billing.learn-more")!, buttonTextSecondary: t("billing.learn-more")!,
current: currentPlan === plansConstant.team current: subscription?.slug === "team" || subscription?.slug === "team-annual"
}, },
{ {
key: 3, key: 3,
@@ -46,7 +42,7 @@ export default function SettingsBilling() {
subtext: t("billing.professional.subtext")!, subtext: t("billing.professional.subtext")!,
buttonTextMain: t("billing.upgrade")!, buttonTextMain: t("billing.upgrade")!,
buttonTextSecondary: t("billing.learn-more")!, buttonTextSecondary: t("billing.learn-more")!,
current: currentPlan === plansConstant.professional current: subscription?.slug === "pro" || subscription?.slug === "pro-annual"
}, },
{ {
key: 4, key: 4,
@@ -55,26 +51,10 @@ export default function SettingsBilling() {
text: "Boost the security and efficiency of your engineering teams.", text: "Boost the security and efficiency of your engineering teams.",
buttonTextMain: t("billing.schedule-demo")!, buttonTextMain: t("billing.schedule-demo")!,
buttonTextSecondary: t("billing.learn-more")!, buttonTextSecondary: t("billing.learn-more")!,
current: false current: subscription?.slug === "enterprise"
} }
]; ];
useEffect(() => {
(async () => {
const orgId = localStorage.getItem("orgData.id") as string;
const subscriptions = await getOrganizationSubscriptions({
orgId
});
if (subscriptions) {
setCurrentPlan(subscriptions.data[0].plan.product);
}
const orgUsers = await getOrganizationUsers({
orgId
});
setNumUsers(orgUsers.length);
})();
}, []);
return ( return (
<div className="flex flex-col justify-between bg-bunker-800 pb-4 text-white"> <div className="flex flex-col justify-between bg-bunker-800 pb-4 text-white">
<Head> <Head>
@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { plans } from "public/data/frequentConstants";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import NavHeader from "@app/components/navigation/NavHeader"; import NavHeader from "@app/components/navigation/NavHeader";