mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
Compare commits
1 Commits
develop
...
fix-renew-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e293bbae8c |
@@ -32,6 +32,7 @@ import { BrandingTemplatesDrawer } from '@/containers/BrandingTemplates/Branding
|
|||||||
|
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
import { InvoiceSendMailDrawer } from '@/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer';
|
import { InvoiceSendMailDrawer } from '@/containers/Sales/Invoices/InvoiceSendMailDrawer/InvoiceSendMailDrawer';
|
||||||
|
import { NewSubscriptionDrawer } from '@/containers/Subscriptions/drawers/NewSubscriptionDrawer/NewSubscriptionDrawer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drawers container of the dashboard.
|
* Drawers container of the dashboard.
|
||||||
@@ -72,6 +73,7 @@ export default function DrawersContainer() {
|
|||||||
<TaxRateDetailsDrawer name={DRAWERS.TAX_RATE_DETAILS} />
|
<TaxRateDetailsDrawer name={DRAWERS.TAX_RATE_DETAILS} />
|
||||||
<CategorizeTransactionDrawer name={DRAWERS.CATEGORIZE_TRANSACTION} />
|
<CategorizeTransactionDrawer name={DRAWERS.CATEGORIZE_TRANSACTION} />
|
||||||
<ChangeSubscriptionPlanDrawer name={DRAWERS.CHANGE_SUBSCARIPTION_PLAN} />
|
<ChangeSubscriptionPlanDrawer name={DRAWERS.CHANGE_SUBSCARIPTION_PLAN} />
|
||||||
|
<NewSubscriptionDrawer name={DRAWERS.NEW_SUBSCRIPTION_PLANS} />
|
||||||
<InvoiceCustomizeDrawer name={DRAWERS.INVOICE_CUSTOMIZE} />
|
<InvoiceCustomizeDrawer name={DRAWERS.INVOICE_CUSTOMIZE} />
|
||||||
<EstimateCustomizeDrawer name={DRAWERS.ESTIMATE_CUSTOMIZE} />
|
<EstimateCustomizeDrawer name={DRAWERS.ESTIMATE_CUSTOMIZE} />
|
||||||
<ReceiptCustomizeDrawer name={DRAWERS.RECEIPT_CUSTOMIZE} />
|
<ReceiptCustomizeDrawer name={DRAWERS.RECEIPT_CUSTOMIZE} />
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export enum DRAWERS {
|
|||||||
TAX_RATE_DETAILS = 'tax-rate-detail-drawer',
|
TAX_RATE_DETAILS = 'tax-rate-detail-drawer',
|
||||||
CATEGORIZE_TRANSACTION = 'categorize-transaction',
|
CATEGORIZE_TRANSACTION = 'categorize-transaction',
|
||||||
CHANGE_SUBSCARIPTION_PLAN = 'change-subscription-plan',
|
CHANGE_SUBSCARIPTION_PLAN = 'change-subscription-plan',
|
||||||
|
NEW_SUBSCRIPTION_PLANS = 'NEW_SUBSCRIPTION_PLANS',
|
||||||
INVOICE_CUSTOMIZE = 'INVOICE_CUSTOMIZE',
|
INVOICE_CUSTOMIZE = 'INVOICE_CUSTOMIZE',
|
||||||
ESTIMATE_CUSTOMIZE = 'ESTIMATE_CUSTOMIZE',
|
ESTIMATE_CUSTOMIZE = 'ESTIMATE_CUSTOMIZE',
|
||||||
PAYMENT_RECEIPT_CUSTOMIZE = 'PAYMENT_RECEIPT_CUSTOMIZE',
|
PAYMENT_RECEIPT_CUSTOMIZE = 'PAYMENT_RECEIPT_CUSTOMIZE',
|
||||||
@@ -34,5 +35,5 @@ export enum DRAWERS {
|
|||||||
BRANDING_TEMPLATES = 'BRANDING_TEMPLATES',
|
BRANDING_TEMPLATES = 'BRANDING_TEMPLATES',
|
||||||
PAYMENT_INVOICE_PREVIEW = 'PAYMENT_INVOICE_PREVIEW',
|
PAYMENT_INVOICE_PREVIEW = 'PAYMENT_INVOICE_PREVIEW',
|
||||||
STRIPE_PAYMENT_INTEGRATION_EDIT = 'STRIPE_PAYMENT_INTEGRATION_EDIT',
|
STRIPE_PAYMENT_INTEGRATION_EDIT = 'STRIPE_PAYMENT_INTEGRATION_EDIT',
|
||||||
INVOICE_SEND_MAIL = 'INVOICE_SEND_MAIL'
|
INVOICE_SEND_MAIL = 'INVOICE_SEND_MAIL',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import clsx from 'classnames';
|
import clsx from 'classnames';
|
||||||
import { includes } from 'lodash';
|
import { includes } from 'lodash';
|
||||||
import { Box, Group, Stack } from '@/components';
|
|
||||||
import { Button, Card, Classes, Intent, Text } from '@blueprintjs/core';
|
import { Button, Card, Classes, Intent, Text } from '@blueprintjs/core';
|
||||||
|
import { Box, Group, Stack } from '@/components';
|
||||||
import withAlertActions from '../Alert/withAlertActions';
|
import withAlertActions from '../Alert/withAlertActions';
|
||||||
import styles from './BillingSubscription.module.scss';
|
import styles from './BillingSubscription.module.scss';
|
||||||
import withDrawerActions from '../Drawer/withDrawerActions';
|
import withDrawerActions from '../Drawer/withDrawerActions';
|
||||||
@@ -18,12 +18,11 @@ function SubscriptionRoot({ openAlert, openDrawer }) {
|
|||||||
if (!mainSubscription) {
|
if (!mainSubscription) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// Handle cancel subscription button click.
|
||||||
const handleCancelSubBtnClick = () => {
|
const handleCancelSubBtnClick = () => {
|
||||||
openAlert('cancel-main-subscription');
|
openAlert('cancel-main-subscription');
|
||||||
};
|
};
|
||||||
const handleResumeSubBtnClick = () => {
|
// Handle update payment method button click.
|
||||||
openAlert('resume-main-subscription');
|
|
||||||
};
|
|
||||||
const handleUpdatePaymentMethod = () => {
|
const handleUpdatePaymentMethod = () => {
|
||||||
window.LemonSqueezy.Url.Open(
|
window.LemonSqueezy.Url.Open(
|
||||||
mainSubscription.lemonUrls?.updatePaymentMethod,
|
mainSubscription.lemonUrls?.updatePaymentMethod,
|
||||||
@@ -33,6 +32,10 @@ function SubscriptionRoot({ openAlert, openDrawer }) {
|
|||||||
const handleUpgradeBtnClick = () => {
|
const handleUpgradeBtnClick = () => {
|
||||||
openDrawer(DRAWERS.CHANGE_SUBSCARIPTION_PLAN);
|
openDrawer(DRAWERS.CHANGE_SUBSCARIPTION_PLAN);
|
||||||
};
|
};
|
||||||
|
// Handles renew the expired subscription.
|
||||||
|
const handleNewSubscriptionBtnClick = () => {
|
||||||
|
openDrawer(DRAWERS.NEW_SUBSCRIPTION_PLANS);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={styles.root}>
|
<Card className={styles.root}>
|
||||||
@@ -66,50 +69,53 @@ function SubscriptionRoot({ openAlert, openDrawer }) {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Stack align="flex-start" spacing={8} className={styles.actions}>
|
<Stack align="flex-start" spacing={8} className={styles.actions}>
|
||||||
<Button
|
|
||||||
minimal
|
|
||||||
small
|
|
||||||
inline
|
|
||||||
intent={Intent.PRIMARY}
|
|
||||||
onClick={handleUpgradeBtnClick}
|
|
||||||
>
|
|
||||||
Upgrade the Plan
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{mainSubscription.canceled && (
|
{mainSubscription.canceled && (
|
||||||
<Button
|
<Button
|
||||||
minimal
|
minimal
|
||||||
small
|
small
|
||||||
inline
|
inline
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
onClick={handleResumeSubBtnClick}
|
onClick={handleNewSubscriptionBtnClick}
|
||||||
>
|
>
|
||||||
Resume Subscription
|
Renew Subscription
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{!mainSubscription.canceled && (
|
{!mainSubscription.canceled && (
|
||||||
<Button
|
<>
|
||||||
minimal
|
<Button
|
||||||
small
|
minimal
|
||||||
inline
|
small
|
||||||
intent={Intent.PRIMARY}
|
inline
|
||||||
onClick={handleCancelSubBtnClick}
|
intent={Intent.PRIMARY}
|
||||||
>
|
onClick={handleUpgradeBtnClick}
|
||||||
Cancel Subscription
|
>
|
||||||
</Button>
|
Upgrade the Plan
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
minimal
|
||||||
|
small
|
||||||
|
inline
|
||||||
|
intent={Intent.PRIMARY}
|
||||||
|
onClick={handleCancelSubBtnClick}
|
||||||
|
>
|
||||||
|
Cancel Subscription
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
minimal
|
||||||
|
small
|
||||||
|
inline
|
||||||
|
intent={Intent.PRIMARY}
|
||||||
|
onClick={handleUpdatePaymentMethod}
|
||||||
|
>
|
||||||
|
Change Payment Method
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<Button
|
|
||||||
minimal
|
|
||||||
small
|
|
||||||
inline
|
|
||||||
intent={Intent.PRIMARY}
|
|
||||||
onClick={handleUpdatePaymentMethod}
|
|
||||||
>
|
|
||||||
Change Payment Method
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Group position={'apart'} style={{ marginTop: 'auto' }}>
|
<Group position={'apart'} mt={'auto'}>
|
||||||
<Group spacing={4}>
|
<Group spacing={4}>
|
||||||
<Text className={styles.priceAmount}>
|
<Text className={styles.priceAmount}>
|
||||||
{mainSubscription.planPriceFormatted}
|
{mainSubscription.planPriceFormatted}
|
||||||
@@ -120,8 +126,8 @@ function SubscriptionRoot({ openAlert, openDrawer }) {
|
|||||||
{mainSubscription.planPeriod === 'month'
|
{mainSubscription.planPeriod === 'month'
|
||||||
? 'mo'
|
? 'mo'
|
||||||
: mainSubscription.planPeriod === 'year'
|
: mainSubscription.planPeriod === 'year'
|
||||||
? 'yearly'
|
? 'yearly'
|
||||||
: ''}
|
: ''}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
@@ -130,10 +136,10 @@ function SubscriptionRoot({ openAlert, openDrawer }) {
|
|||||||
{mainSubscription.canceled && (
|
{mainSubscription.canceled && (
|
||||||
<Button
|
<Button
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
onClick={handleResumeSubBtnClick}
|
onClick={handleNewSubscriptionBtnClick}
|
||||||
className={styles.subscribeButton}
|
className={styles.subscribeButton}
|
||||||
>
|
>
|
||||||
Resume Subscription
|
Renew Subscription
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Box } from "@/components";
|
||||||
|
import { SubscriptionPlansPeriodSwitcher } from "@/containers/Setup/SetupSubscription/SubscriptionPlansPeriodSwitcher";
|
||||||
|
import { Callout, Classes } from "@blueprintjs/core";
|
||||||
|
import { NewSubscriptionPlans } from "./NewSubscriptionPlans";
|
||||||
|
|
||||||
|
|
||||||
|
export function NewSubscriptionContent() {
|
||||||
|
return (
|
||||||
|
<Box className={Classes.DRAWER_BODY}>
|
||||||
|
<Box
|
||||||
|
maxWidth={1024}
|
||||||
|
margin="0 auto"
|
||||||
|
padding={'50px 20px 80px'}
|
||||||
|
>
|
||||||
|
<Callout style={{ marginBottom: '2rem' }} icon={null}>
|
||||||
|
Simple plans. Simple prices. Only pay for what you really need. All
|
||||||
|
plans come with award-winning 24/7 customer support. Prices do not
|
||||||
|
include applicable taxes.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
<SubscriptionPlansPeriodSwitcher />
|
||||||
|
<NewSubscriptionPlans />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { lazy } from 'react';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { Position } from '@blueprintjs/core';
|
||||||
|
import { Drawer, DrawerHeaderContent, DrawerSuspense } from '@/components';
|
||||||
|
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||||
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
|
||||||
|
const NewSubscriptionContent = lazy(() =>
|
||||||
|
import('./NewSubscriptionContent').then((module) => ({
|
||||||
|
default: module.NewSubscriptionContent,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
function NewSubscriptionDrawerRoot({
|
||||||
|
name,
|
||||||
|
// #withDrawer
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
isOpen={isOpen}
|
||||||
|
name={name}
|
||||||
|
size={'calc(100% - 5px)'}
|
||||||
|
position={Position.BOTTOM}
|
||||||
|
>
|
||||||
|
<DrawerSuspense>
|
||||||
|
<DrawerHeaderContent
|
||||||
|
name={DRAWERS.NEW_SUBSCRIPTION_PLANS}
|
||||||
|
title={'Renew Subscription Plan'}
|
||||||
|
/>
|
||||||
|
<NewSubscriptionContent />
|
||||||
|
</DrawerSuspense>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NewSubscriptionDrawer = R.compose(withDrawers())(
|
||||||
|
NewSubscriptionDrawerRoot,
|
||||||
|
);
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { Intent } from '@blueprintjs/core';
|
||||||
|
import { AppToaster, Group } from '@/components';
|
||||||
|
import { SubscriptionPlan } from '../../component/SubscriptionPlan';
|
||||||
|
import { SubscriptionPlansPeriod } from '@/store/plans/plans.reducer';
|
||||||
|
import { useSubscriptionPlans } from '@/hooks/constants/useSubscriptionPlans';
|
||||||
|
import { withSubscriptionPlanMapper } from '../../component/withSubscriptionPlanMapper';
|
||||||
|
import { useGetLemonSqueezyCheckout } from '@/hooks/query';
|
||||||
|
|
||||||
|
export function NewSubscriptionPlans() {
|
||||||
|
const subscriptionPlans = useSubscriptionPlans();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group spacing={14} noWrap align="stretch">
|
||||||
|
{subscriptionPlans.map((plan, index) => (
|
||||||
|
<NewSubscriptionPlanMapped plan={plan} />
|
||||||
|
))}
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NewSubscriptionPlanMapped = R.compose(
|
||||||
|
withSubscriptionPlanMapper,
|
||||||
|
)(
|
||||||
|
({
|
||||||
|
monthlyVariantId,
|
||||||
|
annuallyVariantId,
|
||||||
|
plansPeriod,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
const { mutateAsync: getLemonCheckout, isLoading } =
|
||||||
|
useGetLemonSqueezyCheckout();
|
||||||
|
|
||||||
|
// Handles the subscribe button click.
|
||||||
|
const handleSubscribe = () => {
|
||||||
|
const variantId =
|
||||||
|
plansPeriod === SubscriptionPlansPeriod.Monthly
|
||||||
|
? monthlyVariantId
|
||||||
|
: annuallyVariantId;
|
||||||
|
|
||||||
|
getLemonCheckout({ variantId })
|
||||||
|
.then((res) => {
|
||||||
|
const checkoutUrl = res.data.data.attributes.url;
|
||||||
|
window.LemonSqueezy.Url.Open(checkoutUrl);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
AppToaster.show({
|
||||||
|
message: 'Something went wrong!',
|
||||||
|
intent: Intent.DANGER,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<SubscriptionPlan
|
||||||
|
{...props}
|
||||||
|
onSubscribe={handleSubscribe}
|
||||||
|
subscribeButtonProps={{ loading: isLoading }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user