| @@ -11,23 +11,23 @@ import { useProviderContext } from '@/context/provider-context' | |||
| const Billing: FC = () => { | |||
| const { t } = useTranslation() | |||
| const { isCurrentWorkspaceManager } = useAppContext() | |||
| const { isCurrentWorkspaceOwner } = useAppContext() | |||
| const [billingUrl, setBillingUrl] = React.useState('') | |||
| const { enableBilling } = useProviderContext() | |||
| useEffect(() => { | |||
| if (!enableBilling && !isCurrentWorkspaceManager) | |||
| if (!enableBilling || !isCurrentWorkspaceOwner) | |||
| return | |||
| (async () => { | |||
| const { url } = await fetchBillingUrl() | |||
| setBillingUrl(url) | |||
| })() | |||
| }, [isCurrentWorkspaceManager]) | |||
| }, [isCurrentWorkspaceOwner]) | |||
| return ( | |||
| <div> | |||
| <PlanComp loc={'billing-page'} /> | |||
| {enableBilling && isCurrentWorkspaceManager && billingUrl && ( | |||
| {enableBilling && isCurrentWorkspaceOwner && billingUrl && ( | |||
| <a className='mt-5 flex px-6 justify-between h-12 items-center bg-gray-50 rounded-xl cursor-pointer' href={billingUrl} target='_blank'> | |||
| <div className='flex items-center'> | |||
| <ReceiptList className='w-4 h-4 text-gray-700' /> | |||
| @@ -9,6 +9,7 @@ import PlanItem from './plan-item' | |||
| import { XClose } from '@/app/components/base/icons/src/vender/line/general' | |||
| import { useProviderContext } from '@/context/provider-context' | |||
| import GridMask from '@/app/components/base/grid-mask' | |||
| import { useAppContext } from '@/context/app-context' | |||
| type Props = { | |||
| onCancel: () => void | |||
| @@ -19,7 +20,8 @@ const Pricing: FC<Props> = ({ | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const { plan } = useProviderContext() | |||
| const { isCurrentWorkspaceOwner } = useAppContext() | |||
| const canPay = isCurrentWorkspaceOwner | |||
| const [planRange, setPlanRange] = React.useState<PlanRange>(PlanRange.monthly) | |||
| return createPortal( | |||
| @@ -41,21 +43,25 @@ const Pricing: FC<Props> = ({ | |||
| currentPlan={plan.type} | |||
| plan={Plan.sandbox} | |||
| planRange={planRange} | |||
| canPay={canPay} | |||
| /> | |||
| <PlanItem | |||
| currentPlan={plan.type} | |||
| plan={Plan.professional} | |||
| planRange={planRange} | |||
| canPay={canPay} | |||
| /> | |||
| <PlanItem | |||
| currentPlan={plan.type} | |||
| plan={Plan.team} | |||
| planRange={planRange} | |||
| canPay={canPay} | |||
| /> | |||
| <PlanItem | |||
| currentPlan={plan.type} | |||
| plan={Plan.enterprise} | |||
| planRange={planRange} | |||
| canPay={canPay} | |||
| /> | |||
| </div> | |||
| </div> | |||
| @@ -16,6 +16,7 @@ type Props = { | |||
| currentPlan: Plan | |||
| plan: Plan | |||
| planRange: PlanRange | |||
| canPay: boolean | |||
| } | |||
| const KeyValue = ({ label, value, tooltip }: { label: string; value: string | number | JSX.Element; tooltip?: string }) => { | |||
| @@ -65,6 +66,7 @@ const PlanItem: FC<Props> = ({ | |||
| plan, | |||
| currentPlan, | |||
| planRange, | |||
| canPay, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const [loading, setLoading] = React.useState(false) | |||
| @@ -75,10 +77,13 @@ const PlanItem: FC<Props> = ({ | |||
| const planInfo = ALL_PLANS[plan] | |||
| const isYear = planRange === PlanRange.yearly | |||
| const isCurrent = plan === currentPlan | |||
| const isPlanDisabled = planInfo.level <= ALL_PLANS[currentPlan].level | |||
| const isPlanDisabled = planInfo.level <= ALL_PLANS[currentPlan].level || (!canPay && plan !== Plan.enterprise) | |||
| const { isCurrentWorkspaceManager } = useAppContext() | |||
| const btnText = (() => { | |||
| if (!canPay && plan !== Plan.enterprise) | |||
| return t('billing.plansCommon.contractOwner') | |||
| if (isCurrent) | |||
| return t('billing.plansCommon.currentPlan') | |||
| @@ -31,7 +31,8 @@ const WorkplaceSelector = () => { | |||
| const handleSwitchWorkspace = async (tenant_id: string) => { | |||
| try { | |||
| if (currentWorkspace?.id === tenant_id) return | |||
| if (currentWorkspace?.id === tenant_id) | |||
| return | |||
| await switchWorkspace({ url: '/workspaces/switch', body: { tenant_id } }) | |||
| notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) | |||
| location.assign(`${location.origin}`) | |||
| @@ -18,6 +18,7 @@ export type AppContextValue = { | |||
| mutateUserProfile: VoidFunction | |||
| currentWorkspace: ICurrentWorkspace | |||
| isCurrentWorkspaceManager: boolean | |||
| isCurrentWorkspaceOwner: boolean | |||
| mutateCurrentWorkspace: VoidFunction | |||
| pageContainerRef: React.RefObject<HTMLDivElement> | |||
| langeniusVersionInfo: LangGeniusVersionResponse | |||
| @@ -83,7 +84,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) => | |||
| const [langeniusVersionInfo, setLangeniusVersionInfo] = useState<LangGeniusVersionResponse>(initialLangeniusVersionInfo) | |||
| const [currentWorkspace, setCurrentWorkspace] = useState<ICurrentWorkspace>(initialWorkspaceInfo) | |||
| const isCurrentWorkspaceManager = useMemo(() => ['owner', 'admin'].includes(currentWorkspace.role), [currentWorkspace.role]) | |||
| const isCurrentWorkspaceOwner = useMemo(() => currentWorkspace.role === 'owner', [currentWorkspace.role]) | |||
| const updateUserProfileAndVersion = useCallback(async () => { | |||
| if (userProfileResponse && !userProfileResponse.bodyUsed) { | |||
| const result = await userProfileResponse.json() | |||
| @@ -118,6 +119,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) => | |||
| useSelector, | |||
| currentWorkspace, | |||
| isCurrentWorkspaceManager, | |||
| isCurrentWorkspaceOwner, | |||
| mutateCurrentWorkspace, | |||
| }}> | |||
| <div className='flex flex-col h-full overflow-y-auto'> | |||
| @@ -20,6 +20,7 @@ const translation = { | |||
| save: 'Save ', | |||
| free: 'Free', | |||
| currentPlan: 'Current Plan', | |||
| contractOwner: 'Contact your workspace owner', | |||
| startForFree: 'Start for free', | |||
| getStartedWith: 'Get started with ', | |||
| contactSales: 'Contact Sales', | |||
| @@ -19,6 +19,7 @@ const translation = { | |||
| year: '年', | |||
| save: '节省', | |||
| currentPlan: '当前计划', | |||
| contractOwner: '联系您的工作区所有者', | |||
| free: '免费', | |||
| startForFree: '免费开始', | |||
| getStartedWith: '开始使用', | |||