Browse Source

zen: check balance on enable billing

Frank 5 months ago
parent
commit
f9117bcc7f
1 changed files with 51 additions and 20 deletions
  1. 51 20
      packages/console/app/src/component/workspace/billing-section.tsx

+ 51 - 20
packages/console/app/src/component/workspace/billing-section.tsx

@@ -4,6 +4,8 @@ import { Billing } from "@opencode/console-core/billing.js"
 import { withActor } from "~/context/auth.withActor"
 import { IconCreditCard } from "~/component/icon"
 import styles from "./billing-section.module.css"
+import { Database, eq } from "@opencode/console-core/drizzle/index.js"
+import { BillingTable } from "@opencode/console-core/schema/billing.sql.js"
 
 const createCheckoutUrl = action(async (workspaceID: string, successUrl: string, cancelUrl: string) => {
   "use server"
@@ -17,12 +19,23 @@ const reload = action(async (form: FormData) => {
   return json(await withActor(() => Billing.reload(), workspaceID), { revalidate: getBillingInfo.key })
 }, "billing.reload")
 
-const disableReload = action(async (form: FormData) => {
+const setReload = action(async (form: FormData) => {
   "use server"
   const workspaceID = form.get("workspaceID")?.toString()
   if (!workspaceID) return { error: "Workspace ID is required" }
-  return json(await withActor(() => Billing.disableReload(), workspaceID), { revalidate: getBillingInfo.key })
-}, "billing.disableReload")
+  const reload = form.get("reload")?.toString() === "true"
+  return json(
+    await Database.use((tx) =>
+      tx
+        .update(BillingTable)
+        .set({
+          reload,
+        })
+        .where(eq(BillingTable.workspaceID, workspaceID)),
+    ),
+    { revalidate: getBillingInfo.key },
+  )
+}, "billing.setReload")
 
 const createSessionUrl = action(async (workspaceID: string, returnUrl: string) => {
   "use server"
@@ -44,7 +57,7 @@ export function BillingSection() {
   const createCheckoutUrlSubmission = useSubmission(createCheckoutUrl)
   const createSessionUrlAction = useAction(createSessionUrl)
   const createSessionUrlSubmission = useSubmission(createSessionUrl)
-  const disableReloadSubmission = useSubmission(disableReload)
+  const setReloadSubmission = useSubmission(setReload)
   const reloadSubmission = useSubmission(reload)
 
   // DUMMY DATA FOR TESTING - UNCOMMENT ONE OF THE SCENARIOS BELOW
@@ -89,6 +102,10 @@ export function BillingSection() {
     return ((balanceInfo()?.balance ?? 0) / 100000000).toFixed(2)
   })
 
+  const hasBalance = createMemo(() => {
+    return (balanceInfo()?.balance ?? 0) > 0 && balanceAmount() !== "0.00"
+  })
+
   return (
     <section class={styles.root}>
       <div data-slot="section-title">
@@ -136,19 +153,32 @@ export function BillingSection() {
             <Show
               when={balanceInfo()?.reload}
               fallback={
-                <button
-                  data-color="primary"
-                  disabled={createCheckoutUrlSubmission.pending}
-                  onClick={async () => {
-                    const baseUrl = window.location.href
-                    const checkoutUrl = await createCheckoutUrlAction(params.id, baseUrl, baseUrl)
-                    if (checkoutUrl) {
-                      window.location.href = checkoutUrl
-                    }
-                  }}
+                <Show
+                  when={hasBalance()}
+                  fallback={
+                    <button
+                      data-color="primary"
+                      disabled={createCheckoutUrlSubmission.pending}
+                      onClick={async () => {
+                        const baseUrl = window.location.href
+                        const checkoutUrl = await createCheckoutUrlAction(params.id, baseUrl, baseUrl)
+                        if (checkoutUrl) {
+                          window.location.href = checkoutUrl
+                        }
+                      }}
+                    >
+                      {createCheckoutUrlSubmission.pending ? "Loading..." : "Enable Billing"}
+                    </button>
+                  }
                 >
-                  {createCheckoutUrlSubmission.pending ? "Loading..." : "Enable Billing"}
-                </button>
+                  <form action={setReload} method="post" data-slot="create-form">
+                    <input type="hidden" name="workspaceID" value={params.id} />
+                    <input type="hidden" name="reload" value="true" />
+                    <button data-color="primary" type="submit" disabled={setReloadSubmission.pending}>
+                      {setReloadSubmission.pending ? "Enabling..." : "Enable Billing"}
+                    </button>
+                  </form>
+                </Show>
               }
             >
               <button
@@ -164,10 +194,11 @@ export function BillingSection() {
               >
                 {createSessionUrlSubmission.pending ? "Loading..." : "Manage Payment Methods"}
               </button>
-              <form action={disableReload} method="post" data-slot="create-form">
+              <form action={setReload} method="post" data-slot="create-form">
                 <input type="hidden" name="workspaceID" value={params.id} />
-                <button data-color="ghost" type="submit" disabled={disableReloadSubmission.pending}>
-                  {disableReloadSubmission.pending ? "Disabling..." : "Disable"}
+                <input type="hidden" name="reload" value="false" />
+                <button data-color="ghost" type="submit" disabled={setReloadSubmission.pending}>
+                  {setReloadSubmission.pending ? "Disabling..." : "Disable"}
                 </button>
               </form>
             </Show>
@@ -176,7 +207,7 @@ export function BillingSection() {
         <div data-slot="usage">
           <Show when={!balanceInfo()?.reload}>
             <Show
-              when={!(balanceAmount() === "0.00" || balanceAmount() === "-0.00")}
+              when={hasBalance()}
               fallback={
                 <p>
                   We'll load <b>$20</b> (+$1.23 processing fee) and reload it when it reaches <b>$5</b>.