feat: wip billing page

This commit is contained in:
Ahmed Bouhuolia
2024-07-28 17:53:51 +02:00
parent 14a9c4ba28
commit 1660df20af
14 changed files with 488 additions and 69 deletions

View File

@@ -15,12 +15,17 @@ interface BillingPageBootProps {
}
export function BillingPageBoot({ children }: BillingPageBootProps) {
const { isLoading: isSubscriptionsLoading, data: subscriptions } =
const { isLoading: isSubscriptionsLoading, data: subscriptionsRes } =
useGetSubscriptions();
const mainSubscription = subscriptionsRes?.subscriptions?.find(
(s) => s.slug === 'main',
);
const value = {
isSubscriptionsLoading,
subscriptions,
subscriptions: subscriptionsRes?.subscriptions,
mainSubscription,
};
return <BillingBoot.Provider value={value}>{children}</BillingBoot.Provider>;
}

View File

@@ -1,9 +1,17 @@
// @ts-nocheck
import { Box, Group } from '@/components';
import { Text } from '@blueprintjs/core';
import { Spinner, Text } from '@blueprintjs/core';
import { Subscription } from './BillingSubscription';
import { useBillingPageBoot } from './BillingPageBoot';
import styles from './BillingPageContent.module.scss';
export function BillingPageContent() {
const { isSubscriptionsLoading, subscriptions } = useBillingPageBoot();
if (isSubscriptionsLoading || !subscriptions) {
return <Spinner size={30} />;
}
return (
<Box className={styles.root}>
<Text>

View File

@@ -12,7 +12,7 @@
.title{
margin: 0;
font-size: 20px;
font-size: 18px;
font-weight: 600;
color: #3D4C58;
}
@@ -56,8 +56,4 @@
}
.actions{
margin-top: 16px;
button{
font-size: 15px;
}
}

View File

@@ -4,25 +4,42 @@ import { Box, Group, Stack } from '@/components';
import { Button, Card, Intent, Text } from '@blueprintjs/core';
import withAlertActions from '../Alert/withAlertActions';
import styles from './BillingSubscription.module.scss';
import withDrawerActions from '../Drawer/withDrawerActions';
import { DRAWERS } from '@/constants/drawers';
import { useBillingPageBoot } from './BillingPageBoot';
function SubscriptionRoot({ openAlert }) {
function SubscriptionRoot({ openAlert, openDrawer }) {
const { mainSubscription } = useBillingPageBoot();
// Can't continue if the main subscription is not loaded.
if (!mainSubscription) {
return null;
}
const handleCancelSubBtnClick = () => {
openAlert('cancel-main-subscription');
};
const handleResumeSubBtnClick = () => {
openAlert('resume-main-subscription');
};
const handleUpdatePaymentMethod = () => {};
const handleUpgradeBtnClick = () => {};
const handleUpdatePaymentMethod = () => {
window.LemonSqueezy.Url.Open(
mainSubscription.lemonUrls?.updatePaymentMethod,
);
};
// Handle upgrade button click.
const handleUpgradeBtnClick = () => {
openDrawer(DRAWERS.CHANGE_SUBSCARIPTION_PLAN);
};
return (
<Card className={styles.root}>
<Stack spacing={8}>
<h1 className={styles.title}>Capital Essential</h1>
<Stack spacing={6}>
<h1 className={styles.title}>{mainSubscription.planName}</h1>
<Group spacing={0} className={styles.period}>
<Text className={styles.periodStatus}>Trial</Text>
<Text className={styles.periodStatus}>
{mainSubscription.statusFormatted}
</Text>
<Text className={styles.periodText}>Trial ends in 10 days.</Text>
</Group>
</Stack>
@@ -43,15 +60,29 @@ function SubscriptionRoot({ openAlert }) {
>
Upgrade the Plan
</Button>
<Button
minimal
small
inline
intent={Intent.PRIMARY}
onClick={handleCancelSubBtnClick}
>
Cancel Subscription
</Button>
{mainSubscription.canceled && (
<Button
minimal
small
inline
intent={Intent.PRIMARY}
onClick={handleResumeSubBtnClick}
>
Resume Subscription
</Button>
)}
{!mainSubscription.canceled && (
<Button
minimal
small
inline
intent={Intent.PRIMARY}
onClick={handleCancelSubBtnClick}
>
Cancel Subscription
</Button>
)}
<Button
minimal
small
@@ -65,22 +96,38 @@ function SubscriptionRoot({ openAlert }) {
<Group position={'apart'} style={{ marginTop: 'auto' }}>
<Group spacing={4}>
<Text className={styles.priceAmount}>$10</Text>
<Text className={styles.pricePeriod}>/ mo</Text>
<Text className={styles.priceAmount}>
{mainSubscription.planPriceFormatted}
</Text>
{mainSubscription.planPeriod && (
<Text className={styles.pricePeriod}>
{mainSubscription.planPeriod === 'month'
? 'mo'
: mainSubscription.planPeriod === 'year'
? 'yearly'
: ''}
</Text>
)}
</Group>
<Box>
<Button
intent={Intent.PRIMARY}
onClick={handleResumeSubBtnClick}
className={styles.subscribeButton}
>
Resume Subscription
</Button>
{mainSubscription.canceled && (
<Button
intent={Intent.PRIMARY}
onClick={handleResumeSubBtnClick}
className={styles.subscribeButton}
>
Resume Subscription
</Button>
)}
</Box>
</Group>
</Card>
);
}
export const Subscription = R.compose(withAlertActions)(SubscriptionRoot);
export const Subscription = R.compose(
withAlertActions,
withDrawerActions,
)(SubscriptionRoot);

View File

@@ -0,0 +1,54 @@
// @ts-nocheck
import * as R from 'ramda';
import { Callout, Classes, Intent } from '@blueprintjs/core';
import { AppToaster, Box } from '@/components';
import { SubscriptionPlans } from '@/containers/Setup/SetupSubscription/SubscriptionPlans';
import { SubscriptionPlansPeriodSwitcher } from '@/containers/Setup/SetupSubscription/SubscriptionPlansPeriodSwitcher';
import { useChangeSubscriptionPlan } from '@/hooks/query/subscription';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { DRAWERS } from '@/constants/drawers';
function ChangeSubscriptionPlanContent({ closeDrawer }) {
const { mutateAsync: changeSubscriptionPlan } = useChangeSubscriptionPlan();
// Handle the subscribe button click.
const handleSubscribe = (variantId: number) => {
changeSubscriptionPlan({ variant_id: variantId })
.then(() => {
closeDrawer(DRAWERS.CHANGE_SUBSCARIPTION_PLAN);
AppToaster.show({
intent: Intent.SUCCESS,
message: 'The subscription plan has been changed successfully.',
});
})
.catch(() => {
AppToaster.show({
intent: Intent.DANGER,
message: 'Something went wrong.',
});
});
};
return (
<Box className={Classes.DRAWER_BODY}>
<Box
style={{
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 />
<SubscriptionPlans onSubscribe={handleSubscribe} />
</Box>
</Box>
);
}
export default R.compose(withDrawerActions)(ChangeSubscriptionPlanContent);