This commit includes a major refactor of UI components to enhance the overall look and feel of the platform. The PageHeader component has been replaced by AccountLayoutHeader across multiple pages including settings, members, and billing. The new AccountLayoutHeader also includes an additional `account` prop, enhancing the component's functionality. Furthermore, this commit includes modifications to the marketing page styling, ensuring better spacing and alignment of features.
127 lines
3.3 KiB
TypeScript
127 lines
3.3 KiB
TypeScript
import { ExclamationTriangleIcon } from '@radix-ui/react-icons';
|
|
|
|
import {
|
|
BillingPortalCard,
|
|
CurrentSubscriptionCard,
|
|
} from '@kit/billing-gateway/components';
|
|
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
|
|
import { If } from '@kit/ui/if';
|
|
import { PageBody } from '@kit/ui/page';
|
|
import { Trans } from '@kit/ui/trans';
|
|
import { cn } from '@kit/ui/utils';
|
|
|
|
import billingConfig from '~/config/billing.config';
|
|
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
|
import { withI18n } from '~/lib/i18n/with-i18n';
|
|
|
|
import { AccountLayoutHeader } from '../_components/account-layout-header';
|
|
import { loadTeamAccountBillingPage } from '../_lib/server/team-account-billing-page.loader';
|
|
import { loadTeamWorkspace } from '../_lib/server/team-account-workspace.loader';
|
|
import { createBillingPortalSession } from '../billing/server-actions';
|
|
import { TeamAccountCheckoutForm } from './_components/team-account-checkout-form';
|
|
|
|
interface Params {
|
|
params: {
|
|
account: string;
|
|
};
|
|
}
|
|
|
|
export const generateMetadata = async () => {
|
|
const i18n = await createI18nServerInstance();
|
|
const title = i18n.t('teams:billing.pageTitle');
|
|
|
|
return {
|
|
title,
|
|
};
|
|
};
|
|
|
|
async function TeamAccountBillingPage({ params }: Params) {
|
|
const workspace = await loadTeamWorkspace(params.account);
|
|
const accountId = workspace.account.id;
|
|
|
|
const [subscription, customerId] =
|
|
await loadTeamAccountBillingPage(accountId);
|
|
|
|
const canManageBilling =
|
|
workspace.account.permissions.includes('billing.manage');
|
|
|
|
const Checkout = () => {
|
|
if (!canManageBilling) {
|
|
return <CannotManageBillingAlert />;
|
|
}
|
|
|
|
return (
|
|
<TeamAccountCheckoutForm customerId={customerId} accountId={accountId} />
|
|
);
|
|
};
|
|
|
|
const BillingPortal = () => {
|
|
if (!canManageBilling || !customerId) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<form action={createBillingPortalSession}>
|
|
<input type="hidden" name={'accountId'} value={accountId} />
|
|
<input type="hidden" name={'slug'} value={params.account} />
|
|
|
|
<BillingPortalCard />
|
|
</form>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<AccountLayoutHeader
|
|
title={<Trans i18nKey={'common:billingTabLabel'} />}
|
|
description={<Trans i18nKey={'common:billingTabDescription'} />}
|
|
account={params.account}
|
|
/>
|
|
|
|
<PageBody>
|
|
<div
|
|
className={cn(`flex w-full flex-col space-y-6`, {
|
|
'mx-auto max-w-2xl ': subscription,
|
|
})}
|
|
>
|
|
<If
|
|
condition={subscription}
|
|
fallback={
|
|
<div>
|
|
<Checkout />
|
|
</div>
|
|
}
|
|
>
|
|
{(subscription) => (
|
|
<CurrentSubscriptionCard
|
|
subscription={subscription}
|
|
config={billingConfig}
|
|
/>
|
|
)}
|
|
</If>
|
|
|
|
<BillingPortal />
|
|
</div>
|
|
</PageBody>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default withI18n(TeamAccountBillingPage);
|
|
|
|
function CannotManageBillingAlert() {
|
|
return (
|
|
<Alert variant={'warning'}>
|
|
<ExclamationTriangleIcon className={'h-4'} />
|
|
|
|
<AlertTitle>
|
|
<Trans i18nKey={'billing:cannotManageBillingAlertTitle'} />
|
|
</AlertTitle>
|
|
|
|
<AlertDescription>
|
|
<Trans i18nKey={'billing:cannotManageBillingAlertDescription'} />
|
|
</AlertDescription>
|
|
</Alert>
|
|
);
|
|
}
|