fix: workspace subscription store added

This commit is contained in:
sriram veeraghanta
2024-06-17 20:01:28 +05:30
parent c03759787d
commit 2b5288c838
5 changed files with 146 additions and 1 deletions

View File

@@ -1,13 +1,101 @@
import { useState } from "react";
import { observer } from "mobx-react";
import Image from "next/image";
import { useParams } from "next/navigation";
import useSWR from "swr";
// ui
import { Tooltip } from "@plane/ui";
import { Tooltip, Button, getButtonStyling } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useInstance, useEventTracker } from "@/hooks/store";
import { usePlatformOS } from "@/hooks/use-platform-os";
// plane web components
import { PlaneOneModal, CloudProductsModal, ProPlanDetailsModal } from "@/plane-web/components/license";
import { useWorkspaceSubscription } from "@/plane-web/hooks/store";
// assets
import PlaneOneLogo from "@/public/plane-logos/plane-one.svg";
// assets
import packageJson from "package.json";
export const WorkspaceEditionBadge = observer(() => {
// params
const { workspaceSlug } = useParams();
// states
const [isProPlanModalOpen, setIsProPlanModalOpen] = useState(false);
const [isProPlanDetailsModalOpen, setProPlanDetailsModalOpen] = useState(false);
const [isPlaneOneModalOpen, setIsPlaneOneModalOpen] = useState(false);
// hooks
const { captureEvent } = useEventTracker();
const { isMobile } = usePlatformOS();
const { instance } = useInstance();
const { fetchWorkspaceSubscribedPlan, subscribedPlan } = useWorkspaceSubscription();
// fetch workspace current plane information
useSWR(
workspaceSlug && process.env.NEXT_PUBLIC_IS_MULTI_TENANT === "1" ? `WORKSPACE_CURRENT_PLAN_${workspaceSlug}` : null,
workspaceSlug && process.env.NEXT_PUBLIC_IS_MULTI_TENANT === "1"
? () => fetchWorkspaceSubscribedPlan(workspaceSlug.toString())
: null,
{
errorRetryCount: 2,
}
);
const handleProPlanPurchaseModalOpen = () => {
setIsProPlanModalOpen(true);
captureEvent("pro_plan_modal_opened", {});
};
const handlePlaneOneModalOpen = () => {
setIsPlaneOneModalOpen(true);
captureEvent("plane_one_modal_opened", {});
};
if (process.env.NEXT_PUBLIC_IS_MULTI_TENANT === "1") {
return (
<>
<CloudProductsModal isOpen={isProPlanModalOpen} handleClose={() => setIsProPlanModalOpen(false)} />
<ProPlanDetailsModal isOpen={isProPlanDetailsModalOpen} handleClose={() => setProPlanDetailsModalOpen(false)} />
{subscribedPlan === "FREE" && (
<Button
variant="outline-primary"
className="w-full cursor-pointer rounded-2xl px-3 py-1.5 text-center text-sm font-medium outline-none"
onClick={handleProPlanPurchaseModalOpen}
>
Upgrade to Pro
</Button>
)}
{subscribedPlan === "PRO" && (
<div className="w-full flex justify-start">
<span className="items-center justify-center px-3.5 py-0.5 text-xs leading-4 rounded-xl bg-custom-primary-100/10 text-custom-primary-100">
Pro
</span>
</div>
)}
</>
);
}
if (instance?.product === "plane-one") {
return (
<>
<PlaneOneModal isOpen={isPlaneOneModalOpen} handleClose={() => setIsPlaneOneModalOpen(false)} />
<Tooltip tooltipContent={`Version: ${instance.current_version}`} isMobile={isMobile}>
<button
tabIndex={-1}
className={cn(
getButtonStyling("accent-primary", "md"),
"w-fit cursor-pointer rounded-2xl px-3 py-1.5 text-center text-sm font-medium outline-none"
)}
onClick={handlePlaneOneModalOpen}
>
<Image src={PlaneOneLogo} alt="Plane One" width={24} height={24} />
{"Plane One"}
</button>
</Tooltip>
</>
);
}
return (
<Tooltip tooltipContent={`Version: v${packageJson.version}`} isMobile={isMobile}>

View File

@@ -1,2 +1,3 @@
export * from "./use-workspace-page-details";
export * from "./use-workspace-pages";
export * from "./use-workspace-subscription";

View File

@@ -0,0 +1,11 @@
import { useContext } from "react";
// context
import { StoreContext } from "@/lib/store-context";
// plane web stores
import { IWorkspaceSubscriptionStore } from "@/plane-web/store/subscription/subscription.store";
export const useWorkspaceSubscription = (): IWorkspaceSubscriptionStore => {
const context = useContext(StoreContext);
if (context === undefined) throw new Error("useWorkspaceSubscription must be used within StoreProvider");
return context.workspaceSubscription;
};

View File

@@ -1,18 +1,25 @@
// plane web store
import { IWorkspacePageStore, WorkspacePageStore } from "@/plane-web/store/pages/workspace-page.store";
// store
import {
IWorkspaceSubscriptionStore,
WorkspaceSubscriptionStore,
} from "@/plane-web/store/subscription/subscription.store";
import { CoreRootStore } from "@/store/root.store";
export class RootStore extends CoreRootStore {
workspacePages: IWorkspacePageStore;
workspaceSubscription: IWorkspaceSubscriptionStore;
constructor() {
super();
this.workspacePages = new WorkspacePageStore(this);
this.workspaceSubscription = new WorkspaceSubscriptionStore();
}
resetOnSignOut() {
super.resetOnSignOut();
this.workspacePages = new WorkspacePageStore(this);
this.workspaceSubscription = new WorkspaceSubscriptionStore();
}
}

View File

@@ -0,0 +1,38 @@
import { action, makeObservable, observable, runInAction } from "mobx";
// types
import { IWorkspaceProductSubscription } from "@plane/types";
// services
import { DiscoService } from "@/services/disco.service";
const discoService = new DiscoService();
export interface IWorkspaceSubscriptionStore {
subscribedPlan: "FREE" | "PRO";
fetchWorkspaceSubscribedPlan: (workspaceSlug: string) => Promise<IWorkspaceProductSubscription>;
}
export class WorkspaceSubscriptionStore implements IWorkspaceSubscriptionStore {
subscribedPlan: "FREE" | "PRO" = "FREE";
constructor() {
makeObservable(this, {
subscribedPlan: observable.ref,
fetchWorkspaceSubscribedPlan: action,
});
}
fetchWorkspaceSubscribedPlan = async (workspaceSlug: string) => {
try {
const response = await discoService.getWorkspaceCurrentPlane(workspaceSlug);
runInAction(() => {
this.subscribedPlan = response.product;
});
return response;
} catch (error) {
runInAction(() => {
this.subscribedPlan = "FREE";
});
throw error;
}
};
}