From c6ef92634d0ae026a59e023e69847b481975462b Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 28 Aug 2025 16:44:55 -0400 Subject: wip cloud --- cloud/app/src/routes/[workspaceID].tsx | 186 +++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 7 deletions(-) (limited to 'cloud/app/src/routes') diff --git a/cloud/app/src/routes/[workspaceID].tsx b/cloud/app/src/routes/[workspaceID].tsx index 706a64323..98d03753f 100644 --- a/cloud/app/src/routes/[workspaceID].tsx +++ b/cloud/app/src/routes/[workspaceID].tsx @@ -1,15 +1,187 @@ -import { createAsync, query } from "@solidjs/router" +import { Billing } from "@opencode/cloud-core/billing.js" +import { Key } from "@opencode/cloud-core/key.js" +import { action, createAsync, revalidate, query, useAction, useSubmission } from "@solidjs/router" +import { createSignal, For, Show } from "solid-js" import { getActor, withActor } from "~/context/auth" -const getPosts = query(async () => { +///////////////////////////////////// +// Keys related queries and actions +///////////////////////////////////// + +const listKeys = query(async () => { + "use server" + return withActor(() => Key.list()) +}, "keys") + +const createKey = action(async (name: string) => { + "use server" + return withActor(() => Key.create({ name })) +}, "createKey") + +const removeKey = action(async (id: string) => { "use server" - return withActor(() => { - return "ok" + return withActor(() => Key.remove({ id })) +}, "removeKey") + +///////////////////////////////////// +// Billing related queries and actions +///////////////////////////////////// + +const getBillingInfo = query(async () => { + "use server" + return withActor(async () => { + const billing = await Billing.get() + const payments = await Billing.payments() + const usage = await Billing.usages() + return { billing, payments, usage } }) -}, "posts") +}, "billingInfo") + +const createCheckoutUrl = action(async (successUrl: string, cancelUrl: string) => { + "use server" + return withActor(() => Billing.generateCheckoutUrl({ successUrl, cancelUrl })) +}, "checkoutUrl") +const createPortalUrl = action(async (returnUrl: string) => { + "use server" + return withActor(() => Billing.generatePortalUrl({ returnUrl })) +}, "portalUrl") + +//export const route = { +// preload: () => listKeys(), +//} export default function () { - const actor = createAsync(async () => getActor()) - return
{JSON.stringify(actor())}
+ const actor = createAsync(() => getActor()) + const keys = createAsync(() => listKeys()) + const createKeyAction = useAction(createKey) + const removeKeyAction = useAction(removeKey) + const createKeySubmission = useSubmission(createKey) + const [showCreateForm, setShowCreateForm] = createSignal(false) + const [keyName, setKeyName] = createSignal("") + + const formatDate = (date: Date) => { + return date.toLocaleDateString() + } + + const formatKey = (key: string) => { + if (key.length <= 11) return key + return `${key.slice(0, 7)}...${key.slice(-4)}` + } + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(text) + } catch (error) { + console.error("Failed to copy to clipboard:", error) + } + } + + const handleCreateKey = async () => { + if (!keyName().trim()) return + + try { + await createKeyAction(keyName().trim()) + revalidate("keys") + setKeyName("") + setShowCreateForm(false) + } catch (error) { + console.error("Failed to create API key:", error) + } + } + + const handleDeleteKey = async (keyId: string) => { + if (!confirm("Are you sure you want to delete this API key? This action cannot be undone.")) { + return + } + + try { + await removeKeyAction(keyId) + revalidate("keys") + } catch (error) { + console.error("Failed to delete API key:", error) + } + } + + return ( +
+

Actor

+
{JSON.stringify(actor())}
+

API Keys

+ + setKeyName(e.currentTarget.value)} + onKeyPress={(e) => e.key === "Enter" && handleCreateKey()} + /> +
+ + +
+
+ } + > + + +
+ +

Create an API key to access opencode gateway

+
+ } + > + {(key) => ( +
+
+
{key.name}
+
{formatKey(key.key)}
+
+ Created: {formatDate(key.timeCreated)} + {key.timeUsed && ` • Last used: ${formatDate(key.timeUsed)}`} +
+
+
+ + +
+
+ )} + + + + ) } -- cgit v1.2.3