* Add credits section to billing * create seperate router for credits * add stripe checkout session * schema changes + code improvements * rename to creditBalance * custom quantify input with error message * add checkout session completed webhook endpoint * fix typo * UI fixes * add payCredits handler * add error toast message * allow scheduling sms up as close to 15 minutes in the future * schedule at most 2 hours in advance * webhook to pay for sent sms * continued work on twilio callback * code clean up * further implementation for credit handling * add migration * object as param for scheduleSMS * object as param for sendSMS * fix TrpcSessionUser imports * fix imports * add db changes * add cron job for price setting * twilio status callback to create expense log * remove unused code * set up low credit balance email * fixes for buying credits * fixes in api/twilio/webhook * add test to save credits to credits balance * fix typos * add new helper function chargeCredits * expand twilioProvider * fix type errors * adjust tests * type errors * clean up * clean up * fix subscription active check * remove some user/org related code * more changes to remove user/org support * send emails seperatly to admins * fixes for team billing page * fix stripe success url * fixes to creating expense log * email imrovements and more * get monthly team price from stripe * fix import * fix monthly credits calculation * finsih low credit balance warning email * credit balance limit reached email * create CreditService * cancel SMS and send as email instead * add messageDispatcher * fix type error * fix type error * fix type error * fix import * fix unit test * clean up twilioProvider * clean up chckSmsPrices/route * add missing translations * add skeleton loader * add admin check to get handler * code clean up + fixes * improve scheduling with fallback * fix type error * add bookingUid to handleSendingSMS * add unit tests for creditService * add more tests to credit-service.test.ts * add test for cancelScheduledMessagesAndScheduleEmails * fix test and type error * add back resolve * fix empty resolve * adjust limitReachedAt logic * address mrge comment on styling * add getAdminMembership to repository * twilio/webhook clean up (feedback) * feedback - clean up * remove todo comment * clean up twilio/webhook * code clean up * add use client * add createOneTimeCheckout to stripe service * refactor repository pattern * small fixes + clean up * fix type error * add missing import * fix hasAvailableCredits for user * force-dynamic * rename credits to creditBalance * fix stripe import * remove not needed code * fix e2e tests * improve low balance warning email * dynamic-import CreditService * index.ts * fix e2e tests * remove dynamic import CreditService * Revert "remove dynamic import CreditService" This reverts commit e272978a7ff3fc5a04139e656c9f8d2c84a40dda. * no need to dynamic-import credit service * Revert "no need to dynamic-import credit service" This reverts commit ba5ae488d08979a65fb47b5d0722cda9f45d6ea0. * only select id in getAdminMembership * revert billing/package.json * fix type checks * fix type checks --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: hbjORbj <sldisek783@gmail.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { usePathname } from "next/navigation";
|
|
|
|
import { WEBAPP_URL } from "@calcom/lib/constants";
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import classNames from "@calcom/ui/classNames";
|
|
import { Button } from "@calcom/ui/components/button";
|
|
|
|
import BillingCredits from "~/settings/billing/components/BillingCredits";
|
|
|
|
interface CtaRowProps {
|
|
title: string;
|
|
description: string;
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
declare global {
|
|
interface Window {
|
|
Plain?: {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
init: (config: any) => void;
|
|
open: () => void;
|
|
};
|
|
}
|
|
}
|
|
|
|
export const CtaRow = ({ title, description, className, children }: CtaRowProps) => {
|
|
return (
|
|
<>
|
|
<section className={classNames("text-default flex flex-col sm:flex-row", className)}>
|
|
<div>
|
|
<h2 className="text-base font-semibold">{title}</h2>
|
|
<p>{description}</p>
|
|
</div>
|
|
<div className="flex-shrink-0 pt-3 sm:ml-auto sm:pl-3 sm:pt-0">{children}</div>
|
|
</section>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const BillingView = () => {
|
|
const pathname = usePathname();
|
|
const { t } = useLocale();
|
|
const returnTo = pathname;
|
|
const billingHref = `/api/integrations/stripepayment/portal?returnTo=${WEBAPP_URL}${returnTo}`;
|
|
|
|
const onContactSupportClick = async () => {
|
|
if (window.Plain) {
|
|
window.Plain.open();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="border-subtle space-y-6 rounded-b-lg border border-t-0 px-6 py-8 text-sm sm:space-y-8">
|
|
<CtaRow title={t("view_and_manage_billing_details")} description={t("view_and_edit_billing_details")}>
|
|
<Button color="primary" href={billingHref} target="_blank" EndIcon="external-link">
|
|
{t("billing_portal")}
|
|
</Button>
|
|
</CtaRow>
|
|
</div>
|
|
<BillingCredits />
|
|
<div className="border-subtle mt-6 space-y-6 rounded-lg border px-6 py-8 text-sm sm:space-y-8">
|
|
<CtaRow title={t("need_anything_else")} description={t("further_billing_help")}>
|
|
<Button color="secondary" onClick={onContactSupportClick}>
|
|
{t("contact_support")}
|
|
</Button>
|
|
</CtaRow>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default BillingView;
|