Selaa lähdekoodia

zen: cancel waitlist

Frank 2 kuukautta sitten
vanhempi
sitoutus
e17b875641

+ 0 - 2
packages/console/app/src/routes/black/subscribe/[plan].tsx

@@ -219,8 +219,6 @@ function IntentForm(props: { plan: PlanID; workspaceID: string; onSuccess: (data
       return
     }
 
-    // TODO
-    console.log(setupIntent)
     if (setupIntent?.status === "succeeded") {
       const pm = setupIntent.payment_method as PaymentMethod
 

+ 8 - 0
packages/console/app/src/routes/workspace/[id]/billing/black-waitlist-section.module.css

@@ -0,0 +1,8 @@
+.root {
+  [data-slot="title-row"] {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: var(--space-4);
+  }
+}

+ 57 - 0
packages/console/app/src/routes/workspace/[id]/billing/black-waitlist-section.tsx

@@ -0,0 +1,57 @@
+import { action, useParams, useAction, useSubmission, json, createAsync } from "@solidjs/router"
+import { createStore } from "solid-js/store"
+import { Database, eq } from "@opencode-ai/console-core/drizzle/index.js"
+import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js"
+import { withActor } from "~/context/auth.withActor"
+import { queryBillingInfo } from "../../common"
+import styles from "./black-waitlist-section.module.css"
+
+const cancelWaitlist = action(async (workspaceID: string) => {
+  "use server"
+  return json(
+    await withActor(async () => {
+      await Database.use((tx) =>
+        tx
+          .update(BillingTable)
+          .set({
+            subscriptionPlan: null,
+            timeSubscriptionBooked: null,
+          })
+          .where(eq(BillingTable.workspaceID, workspaceID)),
+      )
+      return { error: undefined }
+    }, workspaceID).catch((e) => ({ error: e.message as string })),
+    { revalidate: queryBillingInfo.key },
+  )
+}, "cancelWaitlist")
+
+export function BlackWaitlistSection() {
+  const params = useParams()
+  const billingInfo = createAsync(() => queryBillingInfo(params.id!))
+  const cancelAction = useAction(cancelWaitlist)
+  const cancelSubmission = useSubmission(cancelWaitlist)
+  const [store, setStore] = createStore({
+    cancelled: false,
+  })
+
+  async function onClickCancel() {
+    const result = await cancelAction(params.id!)
+    if (!result.error) {
+      setStore("cancelled", true)
+    }
+  }
+
+  return (
+    <section class={styles.root}>
+      <div data-slot="section-title">
+        <h2>Waitlist</h2>
+        <div data-slot="title-row">
+          <p>You are on the waitlist for the ${billingInfo()?.subscriptionPlan} per month OpenCode Black plan.</p>
+          <button data-color="danger" disabled={cancelSubmission.pending || store.cancelled} onClick={onClickCancel}>
+            {cancelSubmission.pending ? "Leaving..." : store.cancelled ? "Left" : "Leave Waitlist"}
+          </button>
+        </div>
+      </div>
+    </section>
+  )
+}

+ 5 - 1
packages/console/app/src/routes/workspace/[id]/billing/index.tsx

@@ -3,6 +3,7 @@ import { BillingSection } from "./billing-section"
 import { ReloadSection } from "./reload-section"
 import { PaymentSection } from "./payment-section"
 import { BlackSection } from "./black-section"
+import { BlackWaitlistSection } from "./black-waitlist-section"
 import { Show } from "solid-js"
 import { createAsync, useParams } from "@solidjs/router"
 import { queryBillingInfo, querySessionInfo } from "../../common"
@@ -16,9 +17,12 @@ export default function () {
     <div data-page="workspace-[id]">
       <div data-slot="sections">
         <Show when={sessionInfo()?.isAdmin}>
-          <Show when={billingInfo()?.subscriptionID || billingInfo()?.timeSubscriptionBooked}>
+          <Show when={billingInfo()?.subscriptionID}>
             <BlackSection />
           </Show>
+          <Show when={billingInfo()?.timeSubscriptionBooked}>
+            <BlackWaitlistSection />
+          </Show>
           <BillingSection />
           <Show when={billingInfo()?.customerID}>
             <ReloadSection />